blob: 03c9ee75f48c160977e554bcfe512b61c8d79c51 [file] [log] [blame]
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <vnet/fib/ip6_fib.h>
17#include <vnet/fib/ip4_fib.h>
18#include <vnet/fib/mpls_fib.h>
19#include <vnet/adj/adj.h>
20#include <vnet/dpo/load_balance.h>
21#include <vnet/dpo/load_balance_map.h>
22#include <vnet/dpo/mpls_label_dpo.h>
23#include <vnet/dpo/lookup_dpo.h>
24#include <vnet/dpo/drop_dpo.h>
25#include <vnet/dpo/receive_dpo.h>
Neale Ranns948e00f2016-10-20 13:39:34 +010026#include <vnet/dpo/ip_null_dpo.h>
Neale Ranns88fc83e2017-04-05 08:11:14 -070027#include <vnet/bfd/bfd_main.h>
Neale Ranns43161a82017-08-12 02:12:00 -070028#include <vnet/dpo/interface_rx_dpo.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080029#include <vnet/dpo/replicate_dpo.h>
Neale Ranns6f631152017-10-03 08:20:21 -070030#include <vnet/dpo/l2_bridge_dpo.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010031
32#include <vnet/mpls/mpls.h>
33
Neale Ranns6f631152017-10-03 08:20:21 -070034#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010035#include <vnet/fib/fib_path_list.h>
Neale Rannsad422ed2016-11-02 14:20:04 +000036#include <vnet/fib/fib_entry_src.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010037#include <vnet/fib/fib_walk.h>
38#include <vnet/fib/fib_node_list.h>
Neale Ranns3ee44042016-10-03 13:05:48 +010039#include <vnet/fib/fib_urpf_list.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010040
Neale Ranns88fc83e2017-04-05 08:11:14 -070041/*
42 * Add debugs for passing tests
43 */
44static int fib_test_do_debug;
45
Neale Ranns0bfe5d82016-08-25 15:29:12 +010046#define FIB_TEST_I(_cond, _comment, _args...) \
47({ \
48 int _evald = (_cond); \
49 if (!(_evald)) { \
50 fformat(stderr, "FAIL:%d: " _comment "\n", \
51 __LINE__, ##_args); \
52 } else { \
Neale Ranns88fc83e2017-04-05 08:11:14 -070053 if (fib_test_do_debug) \
54 fformat(stderr, "PASS:%d: " _comment "\n", \
55 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010056 } \
57 _evald; \
58})
59#define FIB_TEST(_cond, _comment, _args...) \
60{ \
61 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
Neale Ranns0ebe8d72016-12-08 19:48:11 +000062 return 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010063 ASSERT(!("FAIL: " _comment)); \
64 } \
65}
66
67/**
68 * A 'i'm not fussed is this is not efficient' store of test data
69 */
70typedef struct test_main_t_ {
71 /**
72 * HW if indicies
73 */
74 u32 hw_if_indicies[4];
75 /**
76 * HW interfaces
77 */
78 vnet_hw_interface_t * hw[4];
79
80} test_main_t;
81static test_main_t test_main;
82
83/* fake ethernet device class, distinct from "fake-ethX" */
84static u8 * format_test_interface_name (u8 * s, va_list * args)
85{
86 u32 dev_instance = va_arg (*args, u32);
87 return format (s, "test-eth%d", dev_instance);
88}
89
90static uword dummy_interface_tx (vlib_main_t * vm,
91 vlib_node_runtime_t * node,
92 vlib_frame_t * frame)
93{
94 clib_warning ("you shouldn't be here, leaking buffers...");
95 return frame->n_vectors;
96}
97
Neale Ranns8b37b872016-11-21 12:25:22 +000098static clib_error_t *
99test_interface_admin_up_down (vnet_main_t * vnm,
100 u32 hw_if_index,
101 u32 flags)
102{
103 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
104 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
105 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
106 return 0;
107}
108
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100109VNET_DEVICE_CLASS (test_interface_device_class,static) = {
110 .name = "Test interface",
111 .format_device_name = format_test_interface_name,
112 .tx_function = dummy_interface_tx,
Neale Ranns8b37b872016-11-21 12:25:22 +0000113 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100114};
115
116static u8 *hw_address;
117
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000118static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100119fib_test_mk_intf (u32 ninterfaces)
120{
121 clib_error_t * error = NULL;
122 test_main_t *tm = &test_main;
123 u8 byte;
124 u32 i;
125
126 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
127
128 for (i=0; i<6; i++)
129 {
130 byte = 0xd0+i;
131 vec_add1(hw_address, byte);
132 }
133
134 for (i = 0; i < ninterfaces; i++)
135 {
136 hw_address[5] = i;
137
138 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000139 test_interface_device_class.index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100140 i /* instance */,
141 hw_address,
142 &tm->hw_if_indicies[i],
143 /* flag change */ 0);
144
145 FIB_TEST((NULL == error), "ADD interface %d", i);
146
Neale Ranns8b37b872016-11-21 12:25:22 +0000147 error = vnet_hw_interface_set_flags(vnet_get_main(),
148 tm->hw_if_indicies[i],
149 VNET_HW_INTERFACE_FLAG_LINK_UP);
150 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100151 tm->hw_if_indicies[i]);
Neale Ranns8b37b872016-11-21 12:25:22 +0000152 vec_validate (ip4_main.fib_index_by_sw_if_index,
153 tm->hw[i]->sw_if_index);
154 vec_validate (ip6_main.fib_index_by_sw_if_index,
155 tm->hw[i]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100156 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
157 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000158
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100159 error = vnet_sw_interface_set_flags(vnet_get_main(),
160 tm->hw[i]->sw_if_index,
161 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
162 FIB_TEST((NULL == error), "UP interface %d", i);
163 }
164 /*
165 * re-eval after the inevitable realloc
166 */
167 for (i = 0; i < ninterfaces; i++)
168 {
169 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
170 tm->hw_if_indicies[i]);
171 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000172
173 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100174}
175
Neale Ranns3ee44042016-10-03 13:05:48 +0100176#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100177{ \
178 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
179 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
180 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
181 fib_table_lookup(fib_index, (_via_prefix))); \
182 FIB_TEST(!dpo_cmp(_via_dpo, \
Neale Ranns3ee44042016-10-03 13:05:48 +0100183 load_balance_get_bucket(_rec_dpo->dpoi_index, \
184 _bucket)), \
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100185 "%U is recursive via %U", \
186 format_fib_prefix, (_rec_prefix), \
187 format_fib_prefix, _via_prefix); \
188}
189
190#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
191{ \
192 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
193 fib_table_lookup_exact_match(fib_index, (_prefix))); \
194 const dpo_id_t *_dpo1 = \
195 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
196 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
197 format_dpo_type, _dpo1->dpoi_type); \
198 FIB_TEST((_ai == _dpo1->dpoi_index), \
199 "%U bucket %d resolves via %U", \
200 format_fib_prefix, (_prefix), \
201 _bucket, \
202 format_dpo_id, _dpo1, 0); \
203}
204
Neale Ranns3ee44042016-10-03 13:05:48 +0100205#define FIB_TEST_RPF(_cond, _comment, _args...) \
206{ \
207 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
208 return (0); \
209 } \
210}
211
212static int
213fib_test_urpf_is_equal (fib_node_index_t fei,
214 fib_forward_chain_type_t fct,
215 u32 num, ...)
216{
Neale Ranns948e00f2016-10-20 13:39:34 +0100217 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100218 fib_urpf_list_t *urpf;
219 index_t ui;
220 va_list ap;
221 int ii;
222
223 va_start(ap, num);
224
225 fib_entry_contribute_forwarding(fei, fct, &dpo);
226 ui = load_balance_get_urpf(dpo.dpoi_index);
227
228 urpf = fib_urpf_list_get(ui);
229
230 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
231 "RPF:%U len %d == %d",
232 format_fib_urpf_list, ui,
233 num, vec_len(urpf->furpf_itfs));
234 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
235 "RPF:%U check-size %d == %d",
236 format_fib_urpf_list, ui,
237 num, vec_len(urpf->furpf_itfs));
238
239 for (ii = 0; ii < num; ii++)
240 {
241 adj_index_t ai = va_arg(ap, adj_index_t);
242
243 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
244 "RPF:%d item:%d - %d == %d",
245 ui, ii, ai, urpf->furpf_itfs[ii]);
246 FIB_TEST_RPF(fib_urpf_check(ui, ai),
247 "RPF:%d %d found",
248 ui, ai);
249 }
250
251 dpo_reset(&dpo);
252
Neale Ranns5899fde2016-10-12 13:51:05 +0100253 va_end(ap);
254
Neale Ranns3ee44042016-10-03 13:05:48 +0100255 return (1);
256}
257
Neale Rannsb80c5362016-10-08 13:03:40 +0100258static u8*
259fib_test_build_rewrite (u8 *eth_addr)
260{
261 u8* rewrite = NULL;
262
263 vec_validate(rewrite, 13);
264
265 memcpy(rewrite, eth_addr, 6);
266 memcpy(rewrite+6, eth_addr, 6);
267
268 return (rewrite);
269}
270
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000271#define FIB_TEST_LB(_cond, _comment, _args...) \
272{ \
273 if (!FIB_TEST_I(_cond, _comment, ##_args)) { \
274 return (0); \
275 } \
276}
277
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800278int
279fib_test_validate_rep_v (const replicate_t *rep,
280 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200281 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800282{
283 const fib_test_rep_bucket_t *exp;
284 const dpo_id_t *dpo;
285 int bucket;
286
287 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
288 "n_buckets = %d", rep->rep_n_buckets);
289
290 for (bucket = 0; bucket < n_buckets; bucket++)
291 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200292 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800293
294 dpo = replicate_get_bucket_i(rep, bucket);
295
296 switch (exp->type)
297 {
298 case FT_REP_LABEL_O_ADJ:
299 {
300 const mpls_label_dpo_t *mld;
301 mpls_label_t hdr;
302 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
303 "bucket %d stacks on %U",
304 bucket,
305 format_dpo_type, dpo->dpoi_type);
306
307 mld = mpls_label_dpo_get(dpo->dpoi_index);
308 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
309
310 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
311 exp->label_o_adj.label),
312 "bucket %d stacks on label %d",
313 bucket,
314 exp->label_o_adj.label);
315
316 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
317 exp->label_o_adj.eos),
318 "bucket %d stacks on label %d %U",
319 bucket,
320 exp->label_o_adj.label,
321 format_mpls_eos_bit, exp->label_o_adj.eos);
322
323 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
324 "bucket %d label stacks on %U",
325 bucket,
326 format_dpo_type, mld->mld_dpo.dpoi_type);
327
328 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
329 "bucket %d label stacks on adj %d",
330 bucket,
331 exp->label_o_adj.adj);
332 }
333 break;
334 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700335 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800336 "bucket %d stacks on %U",
337 bucket,
338 format_dpo_type, dpo->dpoi_type);
339
340 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
341 "bucket %d stacks on adj %d",
342 bucket,
343 exp->adj.adj);
344 break;
345 case FT_REP_DISP_MFIB_LOOKUP:
346// ASSERT(0);
347 break;
348 }
349 }
350
351 return (!0);
352}
353
354int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000355fib_test_validate_lb_v (const load_balance_t *lb,
356 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200357 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000358{
359 const dpo_id_t *dpo;
360 int bucket;
361
362 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
363
364 for (bucket = 0; bucket < n_buckets; bucket++)
365 {
366 const fib_test_lb_bucket_t *exp;
367
Christophe Fontained3c008d2017-10-02 18:10:54 +0200368 exp = va_arg(*ap, fib_test_lb_bucket_t*);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000369 dpo = load_balance_get_bucket_i(lb, bucket);
370
371 switch (exp->type)
372 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000373 case FT_LB_LABEL_STACK_O_ADJ:
374 {
375 const mpls_label_dpo_t *mld;
376 mpls_label_t hdr;
377 u32 ii;
378
379 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
380 "bucket %d stacks on %U",
381 bucket,
382 format_dpo_type, dpo->dpoi_type);
383
384 mld = mpls_label_dpo_get(dpo->dpoi_index);
385
386 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
387 "label stack size",
388 mld->mld_n_labels);
389
390 for (ii = 0; ii < mld->mld_n_labels; ii++)
391 {
392 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
393 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
394 exp->label_stack_o_adj.label_stack[ii]),
395 "bucket %d stacks on label %d",
396 bucket,
397 exp->label_stack_o_adj.label_stack[ii]);
398
399 if (ii == mld->mld_n_labels-1)
400 {
401 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
402 exp->label_o_adj.eos),
403 "bucket %d stacks on label %d %U!=%U",
404 bucket,
405 exp->label_stack_o_adj.label_stack[ii],
406 format_mpls_eos_bit, exp->label_o_adj.eos,
407 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
408 }
409 else
410 {
411 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
412 "bucket %d stacks on label %d %U",
413 bucket,
414 exp->label_stack_o_adj.label_stack[ii],
415 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
416 }
417 }
418
419 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
420 "bucket %d label stacks on %U",
421 bucket,
422 format_dpo_type, mld->mld_dpo.dpoi_type);
423
424 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
425 "bucket %d label stacks on adj %d",
426 bucket,
427 exp->label_stack_o_adj.adj);
428 }
429 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000430 case FT_LB_LABEL_O_ADJ:
431 {
432 const mpls_label_dpo_t *mld;
433 mpls_label_t hdr;
434 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
435 "bucket %d stacks on %U",
436 bucket,
437 format_dpo_type, dpo->dpoi_type);
438
439 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000440 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000441
442 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
443 exp->label_o_adj.label),
444 "bucket %d stacks on label %d",
445 bucket,
446 exp->label_o_adj.label);
447
448 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
449 exp->label_o_adj.eos),
450 "bucket %d stacks on label %d %U",
451 bucket,
452 exp->label_o_adj.label,
453 format_mpls_eos_bit, exp->label_o_adj.eos);
454
455 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
456 "bucket %d label stacks on %U",
457 bucket,
458 format_dpo_type, mld->mld_dpo.dpoi_type);
459
460 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
461 "bucket %d label stacks on adj %d",
462 bucket,
463 exp->label_o_adj.adj);
464 }
465 break;
466 case FT_LB_LABEL_O_LB:
467 {
468 const mpls_label_dpo_t *mld;
469 mpls_label_t hdr;
470
471 FIB_TEST_LB((DPO_MPLS_LABEL == dpo->dpoi_type),
472 "bucket %d stacks on %U",
473 bucket,
474 format_dpo_type, dpo->dpoi_type);
Neale Rannsad422ed2016-11-02 14:20:04 +0000475
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000476 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000477 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000478
Neale Rannsad422ed2016-11-02 14:20:04 +0000479 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
480 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000481 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
482 exp->label_o_lb.label),
483 "bucket %d stacks on label %d",
484 bucket,
485 exp->label_o_lb.label);
486
487 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
488 exp->label_o_lb.eos),
489 "bucket %d stacks on label %d %U",
490 bucket,
491 exp->label_o_lb.label,
492 format_mpls_eos_bit, exp->label_o_lb.eos);
493
494 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
495 "bucket %d label stacks on %U",
496 bucket,
497 format_dpo_type, mld->mld_dpo.dpoi_type);
498
499 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
500 "bucket %d label stacks on LB %d",
501 bucket,
502 exp->label_o_lb.lb);
503 }
504 break;
505 case FT_LB_ADJ:
506 FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
507 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
508 "bucket %d stacks on %U",
509 bucket,
510 format_dpo_type, dpo->dpoi_type);
511 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
512 "bucket %d stacks on adj %d",
513 bucket,
514 exp->adj.adj);
515 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800516 case FT_LB_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700517 FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800518 "bucket %d stacks on %U",
519 bucket,
520 format_dpo_type, dpo->dpoi_type);
521 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
522 "bucket %d stacks on adj %d",
523 bucket,
524 exp->adj.adj);
525 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700526 case FT_LB_L2:
527 FIB_TEST_I((DPO_L2_BRIDGE == dpo->dpoi_type),
528 "bucket %d stacks on %U",
529 bucket,
530 format_dpo_type, dpo->dpoi_type);
531 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
532 "bucket %d stacks on adj %d",
533 bucket,
534 exp->adj.adj);
535 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000536 case FT_LB_O_LB:
537 FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
538 "bucket %d stacks on %U",
539 bucket,
540 format_dpo_type, dpo->dpoi_type);
541 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
Neale Ranns57b58602017-07-15 07:37:25 -0700542 "bucket %d stacks on lb %d not %d",
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000543 bucket,
Neale Ranns57b58602017-07-15 07:37:25 -0700544 dpo->dpoi_index,
545 exp->lb.lb);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000546 break;
547 case FT_LB_SPECIAL:
548 FIB_TEST_I((DPO_DROP == dpo->dpoi_type),
549 "bucket %d stacks on %U",
550 bucket,
551 format_dpo_type, dpo->dpoi_type);
552 FIB_TEST_LB((exp->special.adj == dpo->dpoi_index),
553 "bucket %d stacks on drop %d",
554 bucket,
555 exp->special.adj);
556 break;
557 }
558 }
559 return (!0);
560}
561
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800562int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000563fib_test_validate_entry (fib_node_index_t fei,
564 fib_forward_chain_type_t fct,
565 u16 n_buckets,
566 ...)
567{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000568 dpo_id_t dpo = DPO_INVALID;
569 fib_prefix_t pfx;
570 index_t fw_lbi;
571 u32 fib_index;
572 va_list ap;
573 int res;
574
575 va_start(ap, n_buckets);
576
577 fib_entry_get_prefix(fei, &pfx);
578 fib_index = fib_entry_get_fib_index(fei);
579 fib_entry_contribute_forwarding(fei, fct, &dpo);
580
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800581 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000582 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800583 const replicate_t *rep;
584
585 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200586 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800587 }
588 else
589 {
590 const load_balance_t *lb;
591
592 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
593 "Entry links to %U",
594 format_dpo_type, dpo.dpoi_type);
595
596 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200597 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800598
599 /*
600 * ensure that the LB contributed by the entry is the
601 * same as the LB in the forwarding tables
602 */
603 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000604 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800605 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000606 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800607 case FIB_PROTOCOL_IP4:
608 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx.fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000609 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800610 case FIB_PROTOCOL_IP6:
611 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
612 break;
613 case FIB_PROTOCOL_MPLS:
614 {
615 mpls_unicast_header_t hdr = {
616 .label_exp_s_ttl = 0,
617 };
618
619 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx.fp_label);
620 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx.fp_eos);
621 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
622
623 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
624 break;
625 }
626 default:
627 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000628 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800629 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
630 "Contributed LB = FW LB: %U\n %U",
631 format_load_balance, fw_lbi, 0,
632 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000633 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000634 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000635
636 dpo_reset(&dpo);
637
638 va_end(ap);
639
640 return (res);
641}
642
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000643static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100644fib_test_v4 (void)
645{
646 /*
647 * In the default table check for the presence and correct forwarding
648 * of the special entries
649 */
650 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
651 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
652 const ip_adjacency_t *adj;
653 const load_balance_t *lb;
654 test_main_t *tm;
655 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700656 int lb_count;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100657 int ii;
658
659 /* via 10.10.10.1 */
660 ip46_address_t nh_10_10_10_1 = {
661 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
662 };
663 /* via 10.10.10.2 */
664 ip46_address_t nh_10_10_10_2 = {
665 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
666 };
667
Neale Rannsf12a83f2017-04-18 09:09:40 -0700668 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
669 pool_elts(load_balance_map_pool));
670
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100671 tm = &test_main;
672
Neale Ranns994dab42017-04-18 12:56:45 -0700673 /* record the nubmer of load-balances in use before we start */
674 lb_count = pool_elts(load_balance_pool);
675
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100676 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700677 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
678 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100679
680 for (ii = 0; ii < 4; ii++)
681 {
682 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
683 }
684
685 fib_prefix_t pfx_0_0_0_0_s_0 = {
686 .fp_len = 0,
687 .fp_proto = FIB_PROTOCOL_IP4,
688 .fp_addr = {
689 .ip4 = {
690 {0}
691 },
692 },
693 };
694
695 fib_prefix_t pfx = {
696 .fp_len = 0,
697 .fp_proto = FIB_PROTOCOL_IP4,
698 .fp_addr = {
699 .ip4 = {
700 {0}
701 },
702 },
703 };
704
705 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
706
707 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
708 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
709 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
710 "Default route is DROP");
711
712 pfx.fp_len = 32;
713 fei = fib_table_lookup(fib_index, &pfx);
714 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
715 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
716 "all 0s route is DROP");
717
718 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
719 pfx.fp_len = 32;
720 fei = fib_table_lookup(fib_index, &pfx);
721 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
722 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
723 "all 1s route is DROP");
724
725 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
726 pfx.fp_len = 8;
727 fei = fib_table_lookup(fib_index, &pfx);
728 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
729 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
730 "all-mcast route is DROP");
731
732 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
733 pfx.fp_len = 8;
734 fei = fib_table_lookup(fib_index, &pfx);
735 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
736 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
737 "class-e route is DROP");
738
739 /*
740 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
741 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000742 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
743 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100744 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000745#define ENBR (5+5+2)
746#define PNBR (5+5+6)
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100747 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000748 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100749 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000750 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100751 fib_entry_pool_size());
752
753 /*
754 * add interface routes.
755 * validate presence of /24 attached and /32 recieve.
756 * test for the presence of the receive address in the glean and local adj
757 */
758 fib_prefix_t local_pfx = {
759 .fp_len = 24,
760 .fp_proto = FIB_PROTOCOL_IP4,
761 .fp_addr = {
762 .ip4 = {
763 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
764 },
765 },
766 };
767
768 fib_table_entry_update_one_path(fib_index, &local_pfx,
769 FIB_SOURCE_INTERFACE,
770 (FIB_ENTRY_FLAG_CONNECTED |
771 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -0700772 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100773 NULL,
774 tm->hw[0]->sw_if_index,
775 ~0, // invalid fib index
776 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000777 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100778 FIB_ROUTE_PATH_FLAG_NONE);
779 fei = fib_table_lookup(fib_index, &local_pfx);
780 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
781 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
782 fib_entry_get_flags(fei)),
783 "Flags set on attached interface");
784
785 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700786 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
787 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100788 adj = adj_get(ai);
789 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
790 "attached interface adj is glean");
791 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
792 &adj->sub_type.glean.receive_addr)),
793 "attached interface adj is receive ok");
794
795 local_pfx.fp_len = 32;
796 fib_table_entry_update_one_path(fib_index, &local_pfx,
797 FIB_SOURCE_INTERFACE,
798 (FIB_ENTRY_FLAG_CONNECTED |
799 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -0700800 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100801 NULL,
802 tm->hw[0]->sw_if_index,
803 ~0, // invalid fib index
804 1, // weight
Neale Rannsad422ed2016-11-02 14:20:04 +0000805 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100806 FIB_ROUTE_PATH_FLAG_NONE);
807 fei = fib_table_lookup(fib_index, &local_pfx);
808 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
809 fib_entry_get_flags(fei)),
810 "Flags set on local interface");
811
812 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
813
814 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +0100815 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
816 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100817 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
818 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
819 "local interface adj is local");
820 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
821
822 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
823 &rd->rd_addr)),
824 "local interface adj is receive ok");
825
826 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
827 FIB_PROTOCOL_IP4,
828 FIB_SOURCE_INTERFACE)),
829 "2 Interface Source'd prefixes");
830
831 /*
832 * +2 interface routes +2 non-shared path-lists
833 */
834 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000835 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100836 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000837 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100838 fib_entry_pool_size());
839
840 /*
841 * Modify the default route to be via an adj not yet known.
842 * this sources the defalut route with the API source, which is
843 * a higher preference to the DEFAULT_ROUTE source
844 */
845 pfx.fp_addr.ip4.as_u32 = 0;
846 pfx.fp_len = 0;
847 fib_table_entry_path_add(fib_index, &pfx,
848 FIB_SOURCE_API,
849 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -0700850 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100851 &nh_10_10_10_1,
852 tm->hw[0]->sw_if_index,
853 ~0, // invalid fib index
854 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000855 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100856 FIB_ROUTE_PATH_FLAG_NONE);
857 fei = fib_table_lookup(fib_index, &pfx);
858 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
859 "Flags set on API route");
860
861 FIB_TEST((fei == dfrt), "default route same index");
862 ai = fib_entry_get_adj(fei);
863 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
864 adj = adj_get(ai);
865 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
866 "adj is incomplete");
867 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
868 "adj nbr next-hop ok");
869 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
870 FIB_PROTOCOL_IP4,
871 FIB_SOURCE_API)),
872 "1 API Source'd prefixes");
873
874 /*
875 * find the adj in the shared db
876 */
877 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100878 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100879 &nh_10_10_10_1,
880 tm->hw[0]->sw_if_index);
881 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
882 adj_unlock(locked_ai);
883
884 /*
885 * +1 shared path-list
886 */
887 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
888 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000889 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100890 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000891 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100892 fib_entry_pool_size());
893
894 /*
895 * remove the API source from the default route. We expected
896 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
897 */
898 pfx.fp_addr.ip4.as_u32 = 0;
899 pfx.fp_len = 0;
900 fib_table_entry_path_remove(fib_index, &pfx,
901 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -0700902 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100903 &nh_10_10_10_1,
904 tm->hw[0]->sw_if_index,
905 ~0, // non-recursive path, so no FIB index
906 1,
907 FIB_ROUTE_PATH_FLAG_NONE);
908
909 fei = fib_table_lookup(fib_index, &pfx);
910
911 FIB_TEST((fei == dfrt), "default route same index");
912 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
913 "Default route is DROP");
914
915 /*
916 * -1 shared-path-list
917 */
918 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000919 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100920 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000921 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100922 fib_entry_pool_size());
923
924 /*
925 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
926 */
927 fib_prefix_t pfx_10_10_10_1_s_32 = {
928 .fp_len = 32,
929 .fp_proto = FIB_PROTOCOL_IP4,
930 .fp_addr = {
931 /* 10.10.10.1 */
932 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
933 },
934 };
935 fib_prefix_t pfx_10_10_10_2_s_32 = {
936 .fp_len = 32,
937 .fp_proto = FIB_PROTOCOL_IP4,
938 .fp_addr = {
939 /* 10.10.10.2 */
940 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
941 },
942 };
943 fib_prefix_t pfx_11_11_11_11_s_32 = {
944 .fp_len = 32,
945 .fp_proto = FIB_PROTOCOL_IP4,
946 .fp_addr = {
947 /* 11.11.11.11 */
948 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
949 },
950 };
951 u8 eth_addr[] = {
952 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
953 };
Neale Rannsb80c5362016-10-08 13:03:40 +0100954
Neale Ranns3ee44042016-10-03 13:05:48 +0100955 ip46_address_t nh_12_12_12_12 = {
956 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
957 };
958 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100959
960 /*
961 * Add a route via an incomplete ADJ. then complete the ADJ
962 * Expect the route LB is updated to use complete adj type.
963 */
964 fei = fib_table_entry_update_one_path(fib_index,
965 &pfx_11_11_11_11_s_32,
966 FIB_SOURCE_API,
967 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -0700968 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100969 &pfx_10_10_10_1_s_32.fp_addr,
970 tm->hw[0]->sw_if_index,
971 ~0, // invalid fib index
972 1,
Neale Rannsad422ed2016-11-02 14:20:04 +0000973 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100974 FIB_ROUTE_PATH_FLAG_NONE);
975
976 dpo = fib_entry_contribute_ip_forwarding(fei);
977 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
978 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
979 "11.11.11.11/32 via incomplete adj");
980
981 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +0100982 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100983 &pfx_10_10_10_1_s_32.fp_addr,
984 tm->hw[0]->sw_if_index);
985 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
986 adj = adj_get(ai_01);
987 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
988 "adj is incomplete");
989 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
990 &adj->sub_type.nbr.next_hop)),
991 "adj nbr next-hop ok");
992
Neale Rannsb80c5362016-10-08 13:03:40 +0100993 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
994 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100995 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
996 "adj is complete");
997 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
998 &adj->sub_type.nbr.next_hop)),
999 "adj nbr next-hop ok");
1000 ai = fib_entry_get_adj(fei);
1001 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1002
1003 dpo = fib_entry_contribute_ip_forwarding(fei);
1004 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1005 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1006 "11.11.11.11/32 via complete adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001007 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1008 tm->hw[0]->sw_if_index),
1009 "RPF list for adj-fib contains adj");
1010
1011 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001012 VNET_LINK_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001013 &nh_12_12_12_12,
1014 tm->hw[1]->sw_if_index);
1015 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1016 adj = adj_get(ai_12_12_12_12);
1017 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1018 "adj is incomplete");
1019 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
1020 &adj->sub_type.nbr.next_hop)),
1021 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001022 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1023 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001024 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1025 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001026
1027 /*
1028 * add the adj fib
1029 */
Neale Ranns81424992017-05-18 03:03:22 -07001030 fei = fib_table_entry_path_add(fib_index,
1031 &pfx_10_10_10_1_s_32,
1032 FIB_SOURCE_ADJ,
1033 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001034 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001035 &pfx_10_10_10_1_s_32.fp_addr,
1036 tm->hw[0]->sw_if_index,
1037 ~0, // invalid fib index
1038 1,
1039 NULL,
1040 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001041 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
1042 "Flags set on adj-fib");
1043 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001044 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001045
1046 fib_table_entry_path_remove(fib_index,
1047 &pfx_11_11_11_11_s_32,
1048 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001049 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001050 &pfx_10_10_10_1_s_32.fp_addr,
1051 tm->hw[0]->sw_if_index,
1052 ~0, // invalid fib index
1053 1,
1054 FIB_ROUTE_PATH_FLAG_NONE);
1055
1056 eth_addr[5] = 0xb2;
1057
1058 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01001059 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001060 &pfx_10_10_10_2_s_32.fp_addr,
1061 tm->hw[0]->sw_if_index);
1062 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1063 adj = adj_get(ai_02);
1064 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
1065 "adj is incomplete");
1066 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1067 &adj->sub_type.nbr.next_hop)),
1068 "adj nbr next-hop ok");
1069
Neale Rannsb80c5362016-10-08 13:03:40 +01001070 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
1071 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001072 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
1073 "adj is complete");
1074 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
1075 &adj->sub_type.nbr.next_hop)),
1076 "adj nbr next-hop ok");
1077 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1078
Neale Ranns81424992017-05-18 03:03:22 -07001079 fib_table_entry_path_add(fib_index,
1080 &pfx_10_10_10_2_s_32,
1081 FIB_SOURCE_ADJ,
1082 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001083 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001084 &pfx_10_10_10_2_s_32.fp_addr,
1085 tm->hw[0]->sw_if_index,
1086 ~0, // invalid fib index
1087 1,
1088 NULL,
1089 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001090
1091 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1092 ai = fib_entry_get_adj(fei);
1093 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1094
1095 /*
1096 * +2 adj-fibs, and their non-shared path-lists
1097 */
1098 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001099 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001100 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001101 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001102 fib_entry_pool_size());
1103
1104 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001105 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001106 */
1107 fib_prefix_t pfx_1_1_1_1_s_32 = {
1108 .fp_len = 32,
1109 .fp_proto = FIB_PROTOCOL_IP4,
1110 .fp_addr = {
1111 /* 1.1.1.1/32 */
1112 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1113 },
1114 };
1115
1116 fib_table_entry_path_add(fib_index,
1117 &pfx_1_1_1_1_s_32,
1118 FIB_SOURCE_API,
1119 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001120 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001121 &nh_10_10_10_1,
1122 tm->hw[0]->sw_if_index,
1123 ~0, // invalid fib index
1124 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001125 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001126 FIB_ROUTE_PATH_FLAG_NONE);
1127 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1128 ai = fib_entry_get_adj(fei);
1129 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1130
1131 /*
1132 * +1 entry and a shared path-list
1133 */
1134 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001135 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001136 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001137 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001138 fib_entry_pool_size());
1139
1140 /* 1.1.2.0/24 */
1141 fib_prefix_t pfx_1_1_2_0_s_24 = {
1142 .fp_len = 24,
1143 .fp_proto = FIB_PROTOCOL_IP4,
1144 .fp_addr = {
1145 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1146 }
1147 };
1148
1149 fib_table_entry_path_add(fib_index,
1150 &pfx_1_1_2_0_s_24,
1151 FIB_SOURCE_API,
1152 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001153 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001154 &nh_10_10_10_1,
1155 tm->hw[0]->sw_if_index,
1156 ~0, // invalid fib index
1157 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001158 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001159 FIB_ROUTE_PATH_FLAG_NONE);
1160 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1161 ai = fib_entry_get_adj(fei);
1162 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1163
1164 /*
1165 * +1 entry only
1166 */
1167 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001168 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001169 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001170 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001171 fib_entry_pool_size());
1172
1173 /*
1174 * modify 1.1.2.0/24 to use multipath.
1175 */
1176 fib_table_entry_path_add(fib_index,
1177 &pfx_1_1_2_0_s_24,
1178 FIB_SOURCE_API,
1179 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001180 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001181 &nh_10_10_10_2,
1182 tm->hw[0]->sw_if_index,
1183 ~0, // invalid fib index
1184 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001185 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001186 FIB_ROUTE_PATH_FLAG_NONE);
1187 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1188 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns3ee44042016-10-03 13:05:48 +01001189 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1190 1, tm->hw[0]->sw_if_index),
1191 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001192
1193 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1194 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1195 FIB_TEST((ai_01 == dpo1->dpoi_index),
1196 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
1197 ai_01, dpo1->dpoi_index);
1198
1199 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1200 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1201 FIB_TEST((ai_02 == dpo1->dpoi_index),
1202 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
1203
1204 /*
1205 * +1 shared-pathlist
1206 */
1207 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001208 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001209 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001210 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001211 fib_entry_pool_size());
1212
1213 /*
1214 * revert the modify
1215 */
1216 fib_table_entry_path_remove(fib_index,
1217 &pfx_1_1_2_0_s_24,
1218 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001219 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001220 &nh_10_10_10_2,
1221 tm->hw[0]->sw_if_index,
1222 ~0,
1223 1,
1224 FIB_ROUTE_PATH_FLAG_NONE);
1225 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001226 dpo = fib_entry_contribute_ip_forwarding(fei);
1227 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1228 1, tm->hw[0]->sw_if_index),
1229 "RPF list for 1.1.2.0/24 contains one adj");
1230
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001231 ai = fib_entry_get_adj(fei);
1232 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1233
1234 /*
1235 * +1 shared-pathlist
1236 */
1237 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
1238 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001239 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001240 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001241 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001242 fib_entry_pool_size());
1243
1244 /*
1245 * Add 2 recursive routes:
1246 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1247 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1248 */
1249 fib_prefix_t bgp_100_pfx = {
1250 .fp_len = 32,
1251 .fp_proto = FIB_PROTOCOL_IP4,
1252 .fp_addr = {
1253 /* 100.100.100.100/32 */
1254 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1255 },
1256 };
1257 /* via 1.1.1.1 */
1258 ip46_address_t nh_1_1_1_1 = {
1259 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1260 };
1261
Neale Ranns3ee44042016-10-03 13:05:48 +01001262 fei = fib_table_entry_path_add(fib_index,
1263 &bgp_100_pfx,
1264 FIB_SOURCE_API,
1265 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001266 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001267 &nh_1_1_1_1,
1268 ~0, // no index provided.
1269 fib_index, // nexthop in same fib as route
1270 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001271 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001272 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001273
Neale Ranns3ee44042016-10-03 13:05:48 +01001274 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
1275 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1276 tm->hw[0]->sw_if_index),
1277 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001278
1279 /*
1280 * +1 entry and +1 shared-path-list
1281 */
1282 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1283 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001284 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001285 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001286 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001287 fib_entry_pool_size());
1288
1289 fib_prefix_t bgp_101_pfx = {
1290 .fp_len = 32,
1291 .fp_proto = FIB_PROTOCOL_IP4,
1292 .fp_addr = {
1293 /* 100.100.100.101/32 */
1294 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1295 },
1296 };
1297
1298 fib_table_entry_path_add(fib_index,
1299 &bgp_101_pfx,
1300 FIB_SOURCE_API,
1301 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001302 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001303 &nh_1_1_1_1,
1304 ~0, // no index provided.
1305 fib_index, // nexthop in same fib as route
1306 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001307 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001308 FIB_ROUTE_PATH_FLAG_NONE);
1309
Neale Ranns3ee44042016-10-03 13:05:48 +01001310 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
1311 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1312 tm->hw[0]->sw_if_index),
1313 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001314
1315 /*
1316 * +1 entry, but the recursive path-list is shared.
1317 */
1318 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
1319 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001320 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001321 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001322 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001323 fib_entry_pool_size());
1324
1325 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001326 * An special route; one where the user (me) provides the
1327 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001328 */
1329 fib_prefix_t ex_pfx = {
1330 .fp_len = 32,
1331 .fp_proto = FIB_PROTOCOL_IP4,
1332 .fp_addr = {
1333 /* 4.4.4.4/32 */
1334 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1335 },
1336 };
1337
1338 fib_table_entry_special_add(fib_index,
1339 &ex_pfx,
1340 FIB_SOURCE_SPECIAL,
Neale Rannsa0558302017-04-13 00:44:52 -07001341 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001342 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001343 dpo = fib_entry_contribute_ip_forwarding(fei);
1344 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1345 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
1346 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001347
1348 fib_table_entry_special_remove(fib_index,
1349 &ex_pfx,
1350 FIB_SOURCE_SPECIAL);
1351 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1352 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1353 "Exclusive reoute removed");
1354
1355 /*
1356 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1357 * adjacency through which the route will resovle
1358 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001359 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001360
1361 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1362 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001363 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001364 LOOKUP_INPUT_DST_ADDR,
1365 LOOKUP_TABLE_FROM_CONFIG,
1366 &ex_dpo);
1367
1368 fib_table_entry_special_dpo_add(fib_index,
1369 &ex_pfx,
1370 FIB_SOURCE_SPECIAL,
1371 FIB_ENTRY_FLAG_EXCLUSIVE,
1372 &ex_dpo);
1373 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1374 dpo = fib_entry_contribute_ip_forwarding(fei);
1375 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1376 "exclusive remote uses lookup DPO");
1377
Neale Ranns948e00f2016-10-20 13:39:34 +01001378 /*
1379 * update the exclusive to use a different DPO
1380 */
Neale Ranns450cd302016-11-09 17:49:42 +00001381 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns948e00f2016-10-20 13:39:34 +01001382 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1383 &ex_dpo);
1384 fib_table_entry_special_dpo_update(fib_index,
1385 &ex_pfx,
1386 FIB_SOURCE_SPECIAL,
1387 FIB_ENTRY_FLAG_EXCLUSIVE,
1388 &ex_dpo);
1389 dpo = fib_entry_contribute_ip_forwarding(fei);
1390 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
1391 "exclusive remote uses now uses NULL DPO");
1392
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001393 fib_table_entry_special_remove(fib_index,
1394 &ex_pfx,
1395 FIB_SOURCE_SPECIAL);
1396 FIB_TEST(FIB_NODE_INDEX_INVALID ==
1397 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1398 "Exclusive reoute removed");
1399 dpo_reset(&ex_dpo);
1400
1401 /*
1402 * Add a recursive route:
1403 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1404 */
1405 fib_prefix_t bgp_200_pfx = {
1406 .fp_len = 32,
1407 .fp_proto = FIB_PROTOCOL_IP4,
1408 .fp_addr = {
1409 /* 200.200.200.200/32 */
1410 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1411 },
1412 };
1413 /* via 1.1.1.2 */
1414 fib_prefix_t pfx_1_1_1_2_s_32 = {
1415 .fp_len = 32,
1416 .fp_proto = FIB_PROTOCOL_IP4,
1417 .fp_addr = {
1418 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1419 },
1420 };
1421
Neale Ranns57b58602017-07-15 07:37:25 -07001422 fei = fib_table_entry_path_add(fib_index,
1423 &bgp_200_pfx,
1424 FIB_SOURCE_API,
1425 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001426 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001427 &pfx_1_1_1_2_s_32.fp_addr,
1428 ~0, // no index provided.
1429 fib_index, // nexthop in same fib as route
1430 1,
1431 NULL,
1432 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001433
Neale Ranns57b58602017-07-15 07:37:25 -07001434 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1435 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001436
1437 /*
1438 * the adj should be recursive via drop, since the route resolves via
1439 * the default route, which is itself a DROP
1440 */
1441 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1442 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1443 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01001444 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1445 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001446
1447 /*
1448 * +2 entry and +1 shared-path-list
1449 */
1450 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
1451 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001452 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001453 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001454 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001455 fib_entry_pool_size());
1456
1457 /*
1458 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001459 * The paths are sort by NH first. in this case the the path with greater
1460 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001461 */
1462 fib_prefix_t pfx_1_2_3_4_s_32 = {
1463 .fp_len = 32,
1464 .fp_proto = FIB_PROTOCOL_IP4,
1465 .fp_addr = {
1466 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1467 },
1468 };
1469 fib_table_entry_path_add(fib_index,
1470 &pfx_1_2_3_4_s_32,
1471 FIB_SOURCE_API,
1472 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001473 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001474 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001475 tm->hw[0]->sw_if_index,
1476 ~0,
1477 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001478 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001479 FIB_ROUTE_PATH_FLAG_NONE);
1480 fei = fib_table_entry_path_add(fib_index,
1481 &pfx_1_2_3_4_s_32,
1482 FIB_SOURCE_API,
1483 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001484 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001485 &nh_12_12_12_12,
1486 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001487 ~0,
1488 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001489 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001490 FIB_ROUTE_PATH_FLAG_NONE);
1491
1492 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1493 dpo = fib_entry_contribute_ip_forwarding(fei);
1494 lb = load_balance_get(dpo->dpoi_index);
1495 FIB_TEST((lb->lb_n_buckets == 4),
1496 "1.2.3.4/32 LB has %d bucket",
1497 lb->lb_n_buckets);
1498
Neale Ranns3ee44042016-10-03 13:05:48 +01001499 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1500 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1501 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1502 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001503
Neale Ranns3ee44042016-10-03 13:05:48 +01001504 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1505 tm->hw[0]->sw_if_index,
1506 tm->hw[1]->sw_if_index),
1507 "RPF list for 1.2.3.4/32 contains both adjs");
1508
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001509
1510 /*
1511 * Unequal Cost load-balance. 4:1 ratio.
1512 * fits in a 16 bucket LB with ratio 13:3
1513 */
1514 fib_prefix_t pfx_1_2_3_5_s_32 = {
1515 .fp_len = 32,
1516 .fp_proto = FIB_PROTOCOL_IP4,
1517 .fp_addr = {
1518 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1519 },
1520 };
1521 fib_table_entry_path_add(fib_index,
1522 &pfx_1_2_3_5_s_32,
1523 FIB_SOURCE_API,
1524 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001525 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001526 &nh_12_12_12_12,
1527 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001528 ~0,
1529 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001530 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001531 FIB_ROUTE_PATH_FLAG_NONE);
1532 fei = fib_table_entry_path_add(fib_index,
1533 &pfx_1_2_3_5_s_32,
1534 FIB_SOURCE_API,
1535 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001536 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001537 &nh_10_10_10_1,
1538 tm->hw[0]->sw_if_index,
1539 ~0,
1540 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001541 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001542 FIB_ROUTE_PATH_FLAG_NONE);
1543
1544 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1545 dpo = fib_entry_contribute_ip_forwarding(fei);
1546 lb = load_balance_get(dpo->dpoi_index);
1547 FIB_TEST((lb->lb_n_buckets == 16),
1548 "1.2.3.5/32 LB has %d bucket",
1549 lb->lb_n_buckets);
1550
1551 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1552 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1553 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1554 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1555 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1556 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1557 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1558 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1559 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1560 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1561 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1562 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1563 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001564 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1565 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1566 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1567
1568 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1569 tm->hw[0]->sw_if_index,
1570 tm->hw[1]->sw_if_index),
1571 "RPF list for 1.2.3.4/32 contains both adjs");
1572
1573 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001574 * Test UCMP with a large weight skew - this produces load-balance objects with large
1575 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1576 * laso testing the LB in placce modify code when number of buckets is large.
1577 */
1578 fib_prefix_t pfx_6_6_6_6_s_32 = {
1579 .fp_len = 32,
1580 .fp_proto = FIB_PROTOCOL_IP4,
1581 .fp_addr = {
1582 /* 1.1.1.1/32 */
1583 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1584 },
1585 };
Neale Ranns81424992017-05-18 03:03:22 -07001586 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001587 .type = FT_LB_ADJ,
1588 .adj = {
1589 .adj = ai_01,
1590 },
1591 };
Neale Ranns81424992017-05-18 03:03:22 -07001592 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001593 .type = FT_LB_ADJ,
1594 .adj = {
1595 .adj = ai_02,
1596 },
1597 };
1598 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1599 .type = FT_LB_ADJ,
1600 .adj = {
1601 .adj = ai_12_12_12_12,
1602 },
1603 };
1604 fib_table_entry_update_one_path(fib_index,
1605 &pfx_6_6_6_6_s_32,
1606 FIB_SOURCE_API,
1607 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001608 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001609 &nh_10_10_10_1,
1610 tm->hw[0]->sw_if_index,
1611 ~0, // invalid fib index
1612 0, // zero weigth
Neale Rannsad422ed2016-11-02 14:20:04 +00001613 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001614 FIB_ROUTE_PATH_FLAG_NONE);
1615
1616 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1617 FIB_TEST(fib_test_validate_entry(fei,
1618 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1619 1,
Neale Ranns81424992017-05-18 03:03:22 -07001620 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001621 "6.6.6.6/32 via 10.10.10.1");
1622
1623 fib_table_entry_path_add(fib_index,
1624 &pfx_6_6_6_6_s_32,
1625 FIB_SOURCE_API,
1626 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001627 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001628 &nh_10_10_10_2,
1629 tm->hw[0]->sw_if_index,
1630 ~0, // invalid fib index
1631 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001632 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001633 FIB_ROUTE_PATH_FLAG_NONE);
1634
1635 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1636 FIB_TEST(fib_test_validate_entry(fei,
1637 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1638 64,
Neale Ranns81424992017-05-18 03:03:22 -07001639 &ip_o_10_10_10_2,
1640 &ip_o_10_10_10_2,
1641 &ip_o_10_10_10_2,
1642 &ip_o_10_10_10_2,
1643 &ip_o_10_10_10_2,
1644 &ip_o_10_10_10_2,
1645 &ip_o_10_10_10_2,
1646 &ip_o_10_10_10_2,
1647 &ip_o_10_10_10_2,
1648 &ip_o_10_10_10_2,
1649 &ip_o_10_10_10_2,
1650 &ip_o_10_10_10_2,
1651 &ip_o_10_10_10_2,
1652 &ip_o_10_10_10_2,
1653 &ip_o_10_10_10_2,
1654 &ip_o_10_10_10_2,
1655 &ip_o_10_10_10_2,
1656 &ip_o_10_10_10_2,
1657 &ip_o_10_10_10_2,
1658 &ip_o_10_10_10_2,
1659 &ip_o_10_10_10_2,
1660 &ip_o_10_10_10_2,
1661 &ip_o_10_10_10_2,
1662 &ip_o_10_10_10_2,
1663 &ip_o_10_10_10_2,
1664 &ip_o_10_10_10_2,
1665 &ip_o_10_10_10_2,
1666 &ip_o_10_10_10_2,
1667 &ip_o_10_10_10_2,
1668 &ip_o_10_10_10_2,
1669 &ip_o_10_10_10_2,
1670 &ip_o_10_10_10_2,
1671 &ip_o_10_10_10_2,
1672 &ip_o_10_10_10_2,
1673 &ip_o_10_10_10_2,
1674 &ip_o_10_10_10_2,
1675 &ip_o_10_10_10_2,
1676 &ip_o_10_10_10_2,
1677 &ip_o_10_10_10_2,
1678 &ip_o_10_10_10_2,
1679 &ip_o_10_10_10_2,
1680 &ip_o_10_10_10_2,
1681 &ip_o_10_10_10_2,
1682 &ip_o_10_10_10_2,
1683 &ip_o_10_10_10_2,
1684 &ip_o_10_10_10_2,
1685 &ip_o_10_10_10_2,
1686 &ip_o_10_10_10_2,
1687 &ip_o_10_10_10_2,
1688 &ip_o_10_10_10_2,
1689 &ip_o_10_10_10_2,
1690 &ip_o_10_10_10_2,
1691 &ip_o_10_10_10_2,
1692 &ip_o_10_10_10_2,
1693 &ip_o_10_10_10_2,
1694 &ip_o_10_10_10_2,
1695 &ip_o_10_10_10_2,
1696 &ip_o_10_10_10_2,
1697 &ip_o_10_10_10_2,
1698 &ip_o_10_10_10_2,
1699 &ip_o_10_10_10_2,
1700 &ip_o_10_10_10_2,
1701 &ip_o_10_10_10_2,
1702 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001703 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1704
1705 fib_table_entry_path_add(fib_index,
1706 &pfx_6_6_6_6_s_32,
1707 FIB_SOURCE_API,
1708 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001709 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001710 &nh_12_12_12_12,
1711 tm->hw[1]->sw_if_index,
1712 ~0, // invalid fib index
1713 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001714 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001715 FIB_ROUTE_PATH_FLAG_NONE);
1716
1717 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1718 FIB_TEST(fib_test_validate_entry(fei,
1719 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1720 128,
Neale Ranns81424992017-05-18 03:03:22 -07001721 &ip_o_10_10_10_1,
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_2,
1775 &ip_o_10_10_10_2,
1776 &ip_o_10_10_10_2,
1777 &ip_o_10_10_10_2,
1778 &ip_o_10_10_10_2,
1779 &ip_o_10_10_10_2,
1780 &ip_o_10_10_10_2,
1781 &ip_o_10_10_10_2,
1782 &ip_o_10_10_10_2,
1783 &ip_o_10_10_10_2,
1784 &ip_o_10_10_10_2,
1785 &ip_o_10_10_10_2,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001786 &ip_6_6_6_6_o_12_12_12_12,
1787 &ip_6_6_6_6_o_12_12_12_12,
1788 &ip_6_6_6_6_o_12_12_12_12,
1789 &ip_6_6_6_6_o_12_12_12_12,
1790 &ip_6_6_6_6_o_12_12_12_12,
1791 &ip_6_6_6_6_o_12_12_12_12,
1792 &ip_6_6_6_6_o_12_12_12_12,
1793 &ip_6_6_6_6_o_12_12_12_12,
1794 &ip_6_6_6_6_o_12_12_12_12,
1795 &ip_6_6_6_6_o_12_12_12_12,
1796 &ip_6_6_6_6_o_12_12_12_12,
1797 &ip_6_6_6_6_o_12_12_12_12,
1798 &ip_6_6_6_6_o_12_12_12_12,
1799 &ip_6_6_6_6_o_12_12_12_12,
1800 &ip_6_6_6_6_o_12_12_12_12,
1801 &ip_6_6_6_6_o_12_12_12_12,
1802 &ip_6_6_6_6_o_12_12_12_12,
1803 &ip_6_6_6_6_o_12_12_12_12,
1804 &ip_6_6_6_6_o_12_12_12_12,
1805 &ip_6_6_6_6_o_12_12_12_12,
1806 &ip_6_6_6_6_o_12_12_12_12,
1807 &ip_6_6_6_6_o_12_12_12_12,
1808 &ip_6_6_6_6_o_12_12_12_12,
1809 &ip_6_6_6_6_o_12_12_12_12,
1810 &ip_6_6_6_6_o_12_12_12_12,
1811 &ip_6_6_6_6_o_12_12_12_12,
1812 &ip_6_6_6_6_o_12_12_12_12,
1813 &ip_6_6_6_6_o_12_12_12_12,
1814 &ip_6_6_6_6_o_12_12_12_12,
1815 &ip_6_6_6_6_o_12_12_12_12,
1816 &ip_6_6_6_6_o_12_12_12_12,
1817 &ip_6_6_6_6_o_12_12_12_12,
1818 &ip_6_6_6_6_o_12_12_12_12,
1819 &ip_6_6_6_6_o_12_12_12_12,
1820 &ip_6_6_6_6_o_12_12_12_12,
1821 &ip_6_6_6_6_o_12_12_12_12,
1822 &ip_6_6_6_6_o_12_12_12_12,
1823 &ip_6_6_6_6_o_12_12_12_12,
1824 &ip_6_6_6_6_o_12_12_12_12,
1825 &ip_6_6_6_6_o_12_12_12_12,
1826 &ip_6_6_6_6_o_12_12_12_12,
1827 &ip_6_6_6_6_o_12_12_12_12,
1828 &ip_6_6_6_6_o_12_12_12_12,
1829 &ip_6_6_6_6_o_12_12_12_12,
1830 &ip_6_6_6_6_o_12_12_12_12,
1831 &ip_6_6_6_6_o_12_12_12_12,
1832 &ip_6_6_6_6_o_12_12_12_12,
1833 &ip_6_6_6_6_o_12_12_12_12,
1834 &ip_6_6_6_6_o_12_12_12_12,
1835 &ip_6_6_6_6_o_12_12_12_12,
1836 &ip_6_6_6_6_o_12_12_12_12,
1837 &ip_6_6_6_6_o_12_12_12_12,
1838 &ip_6_6_6_6_o_12_12_12_12,
1839 &ip_6_6_6_6_o_12_12_12_12,
1840 &ip_6_6_6_6_o_12_12_12_12,
1841 &ip_6_6_6_6_o_12_12_12_12,
1842 &ip_6_6_6_6_o_12_12_12_12,
1843 &ip_6_6_6_6_o_12_12_12_12,
1844 &ip_6_6_6_6_o_12_12_12_12,
1845 &ip_6_6_6_6_o_12_12_12_12,
1846 &ip_6_6_6_6_o_12_12_12_12,
1847 &ip_6_6_6_6_o_12_12_12_12,
1848 &ip_6_6_6_6_o_12_12_12_12),
1849 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1850
1851 fib_table_entry_path_remove(fib_index,
1852 &pfx_6_6_6_6_s_32,
1853 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001854 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001855 &nh_12_12_12_12,
1856 tm->hw[1]->sw_if_index,
1857 ~0, // invalid fib index
1858 100,
1859 FIB_ROUTE_PATH_FLAG_NONE);
1860
1861 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1862 FIB_TEST(fib_test_validate_entry(fei,
1863 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1864 64,
Neale Ranns81424992017-05-18 03:03:22 -07001865 &ip_o_10_10_10_2,
1866 &ip_o_10_10_10_2,
1867 &ip_o_10_10_10_2,
1868 &ip_o_10_10_10_2,
1869 &ip_o_10_10_10_2,
1870 &ip_o_10_10_10_2,
1871 &ip_o_10_10_10_2,
1872 &ip_o_10_10_10_2,
1873 &ip_o_10_10_10_2,
1874 &ip_o_10_10_10_2,
1875 &ip_o_10_10_10_2,
1876 &ip_o_10_10_10_2,
1877 &ip_o_10_10_10_2,
1878 &ip_o_10_10_10_2,
1879 &ip_o_10_10_10_2,
1880 &ip_o_10_10_10_2,
1881 &ip_o_10_10_10_2,
1882 &ip_o_10_10_10_2,
1883 &ip_o_10_10_10_2,
1884 &ip_o_10_10_10_2,
1885 &ip_o_10_10_10_2,
1886 &ip_o_10_10_10_2,
1887 &ip_o_10_10_10_2,
1888 &ip_o_10_10_10_2,
1889 &ip_o_10_10_10_2,
1890 &ip_o_10_10_10_2,
1891 &ip_o_10_10_10_2,
1892 &ip_o_10_10_10_2,
1893 &ip_o_10_10_10_2,
1894 &ip_o_10_10_10_2,
1895 &ip_o_10_10_10_2,
1896 &ip_o_10_10_10_2,
1897 &ip_o_10_10_10_2,
1898 &ip_o_10_10_10_2,
1899 &ip_o_10_10_10_2,
1900 &ip_o_10_10_10_2,
1901 &ip_o_10_10_10_2,
1902 &ip_o_10_10_10_2,
1903 &ip_o_10_10_10_2,
1904 &ip_o_10_10_10_2,
1905 &ip_o_10_10_10_2,
1906 &ip_o_10_10_10_2,
1907 &ip_o_10_10_10_2,
1908 &ip_o_10_10_10_2,
1909 &ip_o_10_10_10_2,
1910 &ip_o_10_10_10_2,
1911 &ip_o_10_10_10_2,
1912 &ip_o_10_10_10_2,
1913 &ip_o_10_10_10_2,
1914 &ip_o_10_10_10_2,
1915 &ip_o_10_10_10_2,
1916 &ip_o_10_10_10_2,
1917 &ip_o_10_10_10_2,
1918 &ip_o_10_10_10_2,
1919 &ip_o_10_10_10_2,
1920 &ip_o_10_10_10_2,
1921 &ip_o_10_10_10_2,
1922 &ip_o_10_10_10_2,
1923 &ip_o_10_10_10_2,
1924 &ip_o_10_10_10_2,
1925 &ip_o_10_10_10_2,
1926 &ip_o_10_10_10_2,
1927 &ip_o_10_10_10_2,
1928 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001929 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
1930
1931 fib_table_entry_path_remove(fib_index,
1932 &pfx_6_6_6_6_s_32,
1933 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001934 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001935 &nh_10_10_10_2,
1936 tm->hw[0]->sw_if_index,
1937 ~0, // invalid fib index
1938 100,
1939 FIB_ROUTE_PATH_FLAG_NONE);
1940
1941 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
1942 FIB_TEST(fib_test_validate_entry(fei,
1943 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1944 1,
Neale Ranns81424992017-05-18 03:03:22 -07001945 &ip_o_10_10_10_1),
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001946 "6.6.6.6/32 via 10.10.10.1");
1947
1948 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
1949
1950 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001951 * A recursive via the two unequal cost entries
1952 */
1953 fib_prefix_t bgp_44_s_32 = {
1954 .fp_len = 32,
1955 .fp_proto = FIB_PROTOCOL_IP4,
1956 .fp_addr = {
1957 /* 200.200.200.201/32 */
1958 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
1959 },
1960 };
1961 fei = fib_table_entry_path_add(fib_index,
1962 &bgp_44_s_32,
1963 FIB_SOURCE_API,
1964 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001965 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001966 &pfx_1_2_3_4_s_32.fp_addr,
1967 ~0,
1968 fib_index,
1969 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001970 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001971 FIB_ROUTE_PATH_FLAG_NONE);
1972 fei = fib_table_entry_path_add(fib_index,
1973 &bgp_44_s_32,
1974 FIB_SOURCE_API,
1975 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001976 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001977 &pfx_1_2_3_5_s_32.fp_addr,
1978 ~0,
1979 fib_index,
1980 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001981 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01001982 FIB_ROUTE_PATH_FLAG_NONE);
1983
1984 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
1985 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
1986 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1987 tm->hw[0]->sw_if_index,
1988 tm->hw[1]->sw_if_index),
1989 "RPF list for 1.2.3.4/32 contains both adjs");
1990
1991 /*
1992 * test the uRPF check functions
1993 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001994 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01001995 index_t urpfi;
1996
1997 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
1998 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
1999
2000 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
2001 "uRPF check for 68.68.68.68/32 on %d OK",
2002 tm->hw[0]->sw_if_index);
2003 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
2004 "uRPF check for 68.68.68.68/32 on %d OK",
2005 tm->hw[1]->sw_if_index);
2006 FIB_TEST(!fib_urpf_check(urpfi, 99),
2007 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2008 99);
2009 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002010
2011 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002012 &bgp_44_s_32,
2013 FIB_SOURCE_API);
2014 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002015 &pfx_1_2_3_5_s_32,
2016 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002017 fib_table_entry_delete(fib_index,
2018 &pfx_1_2_3_4_s_32,
2019 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002020
2021 /*
2022 * Add a recursive route:
2023 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2024 */
2025 fib_prefix_t bgp_201_pfx = {
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(0xc8c8c8c9),
2031 },
2032 };
2033 /* via 1.1.1.200 */
2034 fib_prefix_t pfx_1_1_1_200_s_32 = {
2035 .fp_len = 32,
2036 .fp_proto = FIB_PROTOCOL_IP4,
2037 .fp_addr = {
2038 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2039 },
2040 };
2041
Neale Ranns57b58602017-07-15 07:37:25 -07002042 fei = fib_table_entry_path_add(fib_index,
2043 &bgp_201_pfx,
2044 FIB_SOURCE_API,
2045 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002046 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002047 &pfx_1_1_1_200_s_32.fp_addr,
2048 ~0, // no index provided.
2049 fib_index, // nexthop in same fib as route
2050 1,
2051 NULL,
2052 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002053
Neale Ranns57b58602017-07-15 07:37:25 -07002054 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2055 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002056
2057 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2058 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
2059 "Flags set on RR via non-attached");
Neale Ranns3ee44042016-10-03 13:05:48 +01002060 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2061 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002062
2063 /*
2064 * +2 entry (BGP & RR) and +1 shared-path-list
2065 */
2066 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2067 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002068 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002069 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002070 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002071 fib_entry_pool_size());
2072
2073 /*
2074 * insert a route that covers the missing 1.1.1.2/32. we epxect
2075 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2076 */
2077 fib_prefix_t pfx_1_1_1_0_s_24 = {
2078 .fp_len = 24,
2079 .fp_proto = FIB_PROTOCOL_IP4,
2080 .fp_addr = {
2081 /* 1.1.1.0/24 */
2082 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2083 },
2084 };
2085
2086 fib_table_entry_path_add(fib_index,
2087 &pfx_1_1_1_0_s_24,
2088 FIB_SOURCE_API,
2089 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002090 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002091 &nh_10_10_10_1,
2092 tm->hw[0]->sw_if_index,
2093 ~0, // invalid fib index
2094 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002095 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002096 FIB_ROUTE_PATH_FLAG_NONE);
2097 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2098 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2099 ai = fib_entry_get_adj(fei);
2100 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2101 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2102 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2103 ai = fib_entry_get_adj(fei);
2104 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2105 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2106 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2107 ai = fib_entry_get_adj(fei);
2108 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2109
2110 /*
2111 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2112 */
2113 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2114 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002115 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002116 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002117 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002118 fib_entry_pool_size());
2119
2120 /*
2121 * the recursive adj for 200.200.200.200 should be updated.
2122 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002123 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2124 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2125 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
2126 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2127 tm->hw[0]->sw_if_index),
2128 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002129
2130 /*
2131 * insert a more specific route than 1.1.1.0/24 that also covers the
2132 * missing 1.1.1.2/32, but not 1.1.1.200/32. we epxect
2133 * 200.200.200.200 to resolve through it.
2134 */
2135 fib_prefix_t pfx_1_1_1_0_s_28 = {
2136 .fp_len = 28,
2137 .fp_proto = FIB_PROTOCOL_IP4,
2138 .fp_addr = {
2139 /* 1.1.1.0/24 */
2140 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2141 },
2142 };
2143
2144 fib_table_entry_path_add(fib_index,
2145 &pfx_1_1_1_0_s_28,
2146 FIB_SOURCE_API,
2147 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002148 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002149 &nh_10_10_10_2,
2150 tm->hw[0]->sw_if_index,
2151 ~0, // invalid fib index
2152 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002153 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002154 FIB_ROUTE_PATH_FLAG_NONE);
2155 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2156 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2157 ai = fib_entry_get_adj(fei);
2158 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2159
2160 /*
2161 * +1 entry. +1 shared path-list
2162 */
2163 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
2164 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002165 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002166 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002167 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002168 fib_entry_pool_size());
2169
2170 /*
2171 * the recursive adj for 200.200.200.200 should be updated.
2172 * 200.200.200.201 remains unchanged.
2173 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002174 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2175 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002176
2177 /*
2178 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2179 */
2180 fib_table_entry_path_remove(fib_index,
2181 &pfx_1_1_1_0_s_28,
2182 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002183 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002184 &nh_10_10_10_2,
2185 tm->hw[0]->sw_if_index,
2186 ~0,
2187 1,
2188 FIB_ROUTE_PATH_FLAG_NONE);
2189 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2190 FIB_NODE_INDEX_INVALID),
2191 "1.1.1.0/28 removed");
2192 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2193 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2194 "1.1.1.0/28 lookup via /24");
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);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002197
2198 /*
2199 * -1 entry. -1 shared path-list
2200 */
2201 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2202 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002203 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002204 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002205 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002206 fib_entry_pool_size());
2207
2208 /*
2209 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2210 */
2211 fib_table_entry_path_remove(fib_index,
2212 &pfx_1_1_1_0_s_24,
2213 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002214 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002215 &nh_10_10_10_1,
2216 tm->hw[0]->sw_if_index,
2217 ~0,
2218 1,
2219 FIB_ROUTE_PATH_FLAG_NONE);
2220 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2221 FIB_NODE_INDEX_INVALID),
2222 "1.1.1.0/24 removed");
2223
2224 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2225 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2226 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002227 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002228 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2229 "1.1.1.200/32 route is DROP");
2230
Neale Ranns57b58602017-07-15 07:37:25 -07002231 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2232 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2233 "201 is drop");
2234 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2235 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2236 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002237
2238 /*
2239 * -1 entry
2240 */
2241 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2242 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002243 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002244 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002245 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002246 fib_entry_pool_size());
2247
2248 /*
2249 * insert the missing 1.1.1.2/32
2250 */
2251 fei = fib_table_entry_path_add(fib_index,
2252 &pfx_1_1_1_2_s_32,
2253 FIB_SOURCE_API,
2254 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002255 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002256 &nh_10_10_10_1,
2257 tm->hw[0]->sw_if_index,
2258 ~0, // invalid fib index
2259 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002260 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002261 FIB_ROUTE_PATH_FLAG_NONE);
2262 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2263 ai = fib_entry_get_adj(fei);
2264 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2265
Neale Ranns57b58602017-07-15 07:37:25 -07002266 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2267 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2268 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002269 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002270
2271 /*
2272 * no change. 1.1.1.2/32 was already there RR sourced.
2273 */
2274 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2275 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002276 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002277 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002278 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002279 fib_entry_pool_size());
2280
2281 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002282 * give 201 a resolved path.
2283 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2284 * only the latter contributes forwarding.
2285 */
2286 fei = fib_table_entry_path_add(fib_index,
2287 &bgp_201_pfx,
2288 FIB_SOURCE_API,
2289 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002290 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002291 &pfx_1_1_1_2_s_32.fp_addr,
2292 ~0,
2293 fib_index,
2294 1,
2295 NULL,
2296 FIB_ROUTE_PATH_FLAG_NONE);
2297 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2298 fib_table_entry_path_remove(fib_index,
2299 &bgp_201_pfx,
2300 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002301 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002302 &pfx_1_1_1_2_s_32.fp_addr,
2303 ~0,
2304 fib_index,
2305 1,
2306 FIB_ROUTE_PATH_FLAG_NONE);
2307
2308 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002309 * remove 200.200.200.201/32 which does not have a valid via FIB
2310 */
2311 fib_table_entry_path_remove(fib_index,
2312 &bgp_201_pfx,
2313 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002314 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002315 &pfx_1_1_1_200_s_32.fp_addr,
2316 ~0, // no index provided.
2317 fib_index,
2318 1,
2319 FIB_ROUTE_PATH_FLAG_NONE);
2320
2321 /*
2322 * -2 entries (BGP and RR). -1 shared path-list;
2323 */
2324 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2325 FIB_NODE_INDEX_INVALID),
2326 "200.200.200.201/32 removed");
2327 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2328 FIB_NODE_INDEX_INVALID),
2329 "1.1.1.200/32 removed");
2330
2331 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2332 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002333 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002334 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002335 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002336 fib_entry_pool_size());
2337
2338 /*
2339 * remove 200.200.200.200/32 which does have a valid via FIB
2340 */
2341 fib_table_entry_path_remove(fib_index,
2342 &bgp_200_pfx,
2343 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002344 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002345 &pfx_1_1_1_2_s_32.fp_addr,
2346 ~0, // no index provided.
2347 fib_index,
2348 1,
2349 FIB_ROUTE_PATH_FLAG_NONE);
2350
2351 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2352 FIB_NODE_INDEX_INVALID),
2353 "200.200.200.200/32 removed");
2354 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2355 FIB_NODE_INDEX_INVALID),
2356 "1.1.1.2/32 still present");
2357
2358 /*
2359 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2360 */
2361 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2362 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002363 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002364 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002365 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002366 fib_entry_pool_size());
2367
2368 /*
2369 * A recursive prefix that has a 2 path load-balance.
2370 * It also shares a next-hop with other BGP prefixes and hence
2371 * test the ref counting of RR sourced prefixes and 2 level LB.
2372 */
2373 const fib_prefix_t bgp_102 = {
2374 .fp_len = 32,
2375 .fp_proto = FIB_PROTOCOL_IP4,
2376 .fp_addr = {
2377 /* 100.100.100.101/32 */
2378 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2379 },
2380 };
2381 fib_table_entry_path_add(fib_index,
2382 &bgp_102,
2383 FIB_SOURCE_API,
2384 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002385 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002386 &pfx_1_1_1_1_s_32.fp_addr,
2387 ~0, // no index provided.
2388 fib_index, // same as route
2389 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002390 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002391 FIB_ROUTE_PATH_FLAG_NONE);
2392 fib_table_entry_path_add(fib_index,
2393 &bgp_102,
2394 FIB_SOURCE_API,
2395 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002396 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002397 &pfx_1_1_1_2_s_32.fp_addr,
2398 ~0, // no index provided.
2399 fib_index, // same as route's FIB
2400 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002401 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002402 FIB_ROUTE_PATH_FLAG_NONE);
2403 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2404 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2405 dpo = fib_entry_contribute_ip_forwarding(fei);
2406
2407 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2408 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2409 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2410 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2411
2412 lb = load_balance_get(dpo->dpoi_index);
2413 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2414 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2415 "First via 10.10.10.1");
2416 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
2417 "Second via 10.10.10.1");
2418
2419 fib_table_entry_path_remove(fib_index,
2420 &bgp_102,
2421 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002422 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002423 &pfx_1_1_1_1_s_32.fp_addr,
2424 ~0, // no index provided.
2425 fib_index, // same as route's FIB
2426 1,
2427 FIB_ROUTE_PATH_FLAG_NONE);
2428 fib_table_entry_path_remove(fib_index,
2429 &bgp_102,
2430 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002431 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002432 &pfx_1_1_1_2_s_32.fp_addr,
2433 ~0, // no index provided.
2434 fib_index, // same as route's FIB
2435 1,
2436 FIB_ROUTE_PATH_FLAG_NONE);
2437 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2438 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2439
2440 /*
2441 * remove the remaining recursives
2442 */
2443 fib_table_entry_path_remove(fib_index,
2444 &bgp_100_pfx,
2445 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002446 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002447 &pfx_1_1_1_1_s_32.fp_addr,
2448 ~0, // no index provided.
2449 fib_index, // same as route's FIB
2450 1,
2451 FIB_ROUTE_PATH_FLAG_NONE);
2452 fib_table_entry_path_remove(fib_index,
2453 &bgp_101_pfx,
2454 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002455 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002456 &pfx_1_1_1_1_s_32.fp_addr,
2457 ~0, // no index provided.
2458 fib_index, // same as route's FIB
2459 1,
2460 FIB_ROUTE_PATH_FLAG_NONE);
2461 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2462 FIB_NODE_INDEX_INVALID),
2463 "100.100.100.100/32 removed");
2464 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2465 FIB_NODE_INDEX_INVALID),
2466 "100.100.100.101/32 removed");
2467
2468 /*
2469 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2470 */
2471 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2472 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002473 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002474 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002475 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002476 fib_entry_pool_size());
2477
2478 /*
2479 * Add a recursive route via a connected cover, using an adj-fib that does exist
2480 */
2481 fib_table_entry_path_add(fib_index,
2482 &bgp_200_pfx,
2483 FIB_SOURCE_API,
2484 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002485 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002486 &nh_10_10_10_1,
2487 ~0, // no index provided.
2488 fib_index, // Same as route's FIB
2489 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002490 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002491 FIB_ROUTE_PATH_FLAG_NONE);
2492
2493 /*
2494 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2495 */
2496 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
2497 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002498 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002499 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002500 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002501 fib_entry_pool_size());
2502
2503 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2504 dpo = fib_entry_contribute_ip_forwarding(fei);
2505
2506 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2507 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2508
2509 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2510 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
2511
2512 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
2513 "Flags set on RR via existing attached");
2514
2515 /*
2516 * Add a recursive route via a connected cover, using and adj-fib that does
2517 * not exist
2518 */
2519 ip46_address_t nh_10_10_10_3 = {
2520 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
2521 };
2522 fib_prefix_t pfx_10_10_10_3 = {
2523 .fp_len = 32,
2524 .fp_proto = FIB_PROTOCOL_IP4,
2525 .fp_addr = nh_10_10_10_3,
2526 };
2527
2528 fib_table_entry_path_add(fib_index,
2529 &bgp_201_pfx,
2530 FIB_SOURCE_API,
2531 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002532 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002533 &nh_10_10_10_3,
2534 ~0, // no index provided.
2535 fib_index,
2536 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002537 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002538 FIB_ROUTE_PATH_FLAG_NONE);
2539
2540 /*
2541 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2542 * one unshared non-recursive via 10.10.10.3
2543 */
2544 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
2545 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002546 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002547 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002548 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002549 fib_entry_pool_size());
2550
2551 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01002552 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002553 &nh_10_10_10_3,
2554 tm->hw[0]->sw_if_index);
2555
2556 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2557 dpo = fib_entry_contribute_ip_forwarding(fei);
2558 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2559 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2560
2561 ai = fib_entry_get_adj(fei);
2562 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2563 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
2564 fib_entry_get_flags(fei)),
2565 "Flags set on RR via non-existing attached");
2566
2567 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
2568 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
2569
2570 adj_unlock(ai_03);
2571
2572 /*
2573 * remove the recursives
2574 */
2575 fib_table_entry_path_remove(fib_index,
2576 &bgp_200_pfx,
2577 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002578 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002579 &nh_10_10_10_1,
2580 ~0, // no index provided.
2581 fib_index, // same as route's FIB
2582 1,
2583 FIB_ROUTE_PATH_FLAG_NONE);
2584 fib_table_entry_path_remove(fib_index,
2585 &bgp_201_pfx,
2586 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002587 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002588 &nh_10_10_10_3,
2589 ~0, // no index provided.
2590 fib_index, // same as route's FIB
2591 1,
2592 FIB_ROUTE_PATH_FLAG_NONE);
2593
2594 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2595 FIB_NODE_INDEX_INVALID),
2596 "200.200.200.201/32 removed");
2597 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2598 FIB_NODE_INDEX_INVALID),
2599 "200.200.200.200/32 removed");
2600 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
2601 FIB_NODE_INDEX_INVALID),
2602 "10.10.10.3/32 removed");
2603
2604 /*
2605 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2606 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2607 */
2608 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2609 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002610 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002611 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002612 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002613 fib_entry_pool_size());
2614
2615
2616 /*
2617 * RECURSION LOOPS
2618 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2619 */
2620 fib_prefix_t pfx_5_5_5_5_s_32 = {
2621 .fp_len = 32,
2622 .fp_proto = FIB_PROTOCOL_IP4,
2623 .fp_addr = {
2624 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2625 },
2626 };
2627 fib_prefix_t pfx_5_5_5_6_s_32 = {
2628 .fp_len = 32,
2629 .fp_proto = FIB_PROTOCOL_IP4,
2630 .fp_addr = {
2631 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2632 },
2633 };
2634 fib_prefix_t pfx_5_5_5_7_s_32 = {
2635 .fp_len = 32,
2636 .fp_proto = FIB_PROTOCOL_IP4,
2637 .fp_addr = {
2638 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2639 },
2640 };
2641
2642 fib_table_entry_path_add(fib_index,
2643 &pfx_5_5_5_5_s_32,
2644 FIB_SOURCE_API,
2645 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002646 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002647 &pfx_5_5_5_6_s_32.fp_addr,
2648 ~0, // no index provided.
2649 fib_index,
2650 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002651 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002652 FIB_ROUTE_PATH_FLAG_NONE);
2653 fib_table_entry_path_add(fib_index,
2654 &pfx_5_5_5_6_s_32,
2655 FIB_SOURCE_API,
2656 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002657 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002658 &pfx_5_5_5_7_s_32.fp_addr,
2659 ~0, // no index provided.
2660 fib_index,
2661 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002662 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002663 FIB_ROUTE_PATH_FLAG_NONE);
2664 fib_table_entry_path_add(fib_index,
2665 &pfx_5_5_5_7_s_32,
2666 FIB_SOURCE_API,
2667 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002668 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002669 &pfx_5_5_5_5_s_32.fp_addr,
2670 ~0, // no index provided.
2671 fib_index,
2672 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002673 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002674 FIB_ROUTE_PATH_FLAG_NONE);
2675 /*
2676 * +3 entries, +3 shared path-list
2677 */
2678 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
2679 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002680 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002681 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002682 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002683 fib_entry_pool_size());
2684
2685 /*
2686 * All the entries have only looped paths, so they are all drop
2687 */
2688 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2689 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2690 "LB for 5.5.5.7/32 is via adj for DROP");
2691 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2692 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2693 "LB for 5.5.5.5/32 is via adj for DROP");
2694 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2695 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2696 "LB for 5.5.5.6/32 is via adj for DROP");
2697
2698 /*
2699 * provide 5.5.5.6/32 with alternate path.
2700 * this will allow only 5.5.5.6/32 to forward with this path, the others
2701 * are still drop since the loop is still present.
2702 */
2703 fib_table_entry_path_add(fib_index,
2704 &pfx_5_5_5_6_s_32,
2705 FIB_SOURCE_API,
2706 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002707 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002708 &nh_10_10_10_1,
2709 tm->hw[0]->sw_if_index,
2710 ~0,
2711 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002712 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002713 FIB_ROUTE_PATH_FLAG_NONE);
2714
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002715 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2716 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2717
2718 lb = load_balance_get(dpo1->dpoi_index);
2719 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2720
2721 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2722 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2723 FIB_TEST((ai_01 == dpo2->dpoi_index),
2724 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
2725
2726 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2727 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2728 "LB for 5.5.5.7/32 is via adj for DROP");
2729 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2730 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2731 "LB for 5.5.5.5/32 is via adj for DROP");
2732
2733 /*
2734 * remove the alternate path for 5.5.5.6/32
2735 * back to all drop
2736 */
2737 fib_table_entry_path_remove(fib_index,
2738 &pfx_5_5_5_6_s_32,
2739 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002740 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002741 &nh_10_10_10_1,
2742 tm->hw[0]->sw_if_index,
2743 ~0,
2744 1,
2745 FIB_ROUTE_PATH_FLAG_NONE);
2746
2747 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2748 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2749 "LB for 5.5.5.7/32 is via adj for DROP");
2750 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2751 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2752 "LB for 5.5.5.5/32 is via adj for DROP");
2753 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2754 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2755 "LB for 5.5.5.6/32 is via adj for DROP");
2756
2757 /*
2758 * break the loop by giving 5.5.5.5/32 a new set of paths
2759 * expect all to forward via this new path.
2760 */
2761 fib_table_entry_update_one_path(fib_index,
2762 &pfx_5_5_5_5_s_32,
2763 FIB_SOURCE_API,
2764 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002765 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002766 &nh_10_10_10_1,
2767 tm->hw[0]->sw_if_index,
2768 ~0, // invalid fib index
2769 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002770 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002771 FIB_ROUTE_PATH_FLAG_NONE);
2772
2773 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2774 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2775 lb = load_balance_get(dpo1->dpoi_index);
2776 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2777
2778 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2779 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2780 FIB_TEST((ai_01 == dpo2->dpoi_index),
2781 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
2782
2783 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2784 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2785
2786 lb = load_balance_get(dpo2->dpoi_index);
2787 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2788 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
2789 "5.5.5.5.7 via 5.5.5.5");
2790
2791 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2792 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2793
2794 lb = load_balance_get(dpo1->dpoi_index);
2795 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2796 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
2797 "5.5.5.5.6 via 5.5.5.7");
2798
2799 /*
2800 * revert back to the loop. so we can remove the prefixes with
2801 * the loop intact
2802 */
2803 fib_table_entry_update_one_path(fib_index,
2804 &pfx_5_5_5_5_s_32,
2805 FIB_SOURCE_API,
2806 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002807 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002808 &pfx_5_5_5_6_s_32.fp_addr,
2809 ~0, // no index provided.
2810 fib_index,
2811 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002812 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002813 FIB_ROUTE_PATH_FLAG_NONE);
2814
2815 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2816 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2817 "LB for 5.5.5.7/32 is via adj for DROP");
2818 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2819 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2820 "LB for 5.5.5.5/32 is via adj for DROP");
2821 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2822 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2823 "LB for 5.5.5.6/32 is via adj for DROP");
2824
2825 /*
2826 * remove all the 5.5.5.x/32 prefixes
2827 */
2828 fib_table_entry_path_remove(fib_index,
2829 &pfx_5_5_5_5_s_32,
2830 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002831 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002832 &pfx_5_5_5_6_s_32.fp_addr,
2833 ~0, // no index provided.
2834 fib_index, // same as route's FIB
2835 1,
2836 FIB_ROUTE_PATH_FLAG_NONE);
2837 fib_table_entry_path_remove(fib_index,
2838 &pfx_5_5_5_6_s_32,
2839 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002840 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002841 &pfx_5_5_5_7_s_32.fp_addr,
2842 ~0, // no index provided.
2843 fib_index, // same as route's FIB
2844 1,
2845 FIB_ROUTE_PATH_FLAG_NONE);
2846 fib_table_entry_path_remove(fib_index,
2847 &pfx_5_5_5_7_s_32,
2848 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002849 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002850 &pfx_5_5_5_5_s_32.fp_addr,
2851 ~0, // no index provided.
2852 fib_index, // same as route's FIB
2853 1,
2854 FIB_ROUTE_PATH_FLAG_NONE);
2855 fib_table_entry_path_remove(fib_index,
2856 &pfx_5_5_5_6_s_32,
2857 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002858 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002859 &nh_10_10_10_2,
2860 ~0, // no index provided.
2861 fib_index, // same as route's FIB
2862 1,
2863 FIB_ROUTE_PATH_FLAG_NONE);
2864
2865 /*
2866 * -3 entries, -3 shared path-list
2867 */
2868 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2869 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002870 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002871 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002872 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002873 fib_entry_pool_size());
2874
2875 /*
2876 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2877 */
2878 fib_table_entry_path_add(fib_index,
2879 &pfx_5_5_5_6_s_32,
2880 FIB_SOURCE_API,
2881 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002882 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002883 &pfx_5_5_5_6_s_32.fp_addr,
2884 ~0, // no index provided.
2885 fib_index,
2886 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002887 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002888 FIB_ROUTE_PATH_FLAG_NONE);
2889 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2890 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2891 "1-level 5.5.5.6/32 loop is via adj for DROP");
2892
2893 fib_table_entry_path_remove(fib_index,
2894 &pfx_5_5_5_6_s_32,
2895 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002896 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002897 &pfx_5_5_5_6_s_32.fp_addr,
2898 ~0, // no index provided.
2899 fib_index, // same as route's FIB
2900 1,
2901 FIB_ROUTE_PATH_FLAG_NONE);
2902 FIB_TEST(FIB_NODE_INDEX_INVALID ==
2903 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
2904 "1-level 5.5.5.6/32 loop is removed");
2905
2906 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002907 * A recursive route whose next-hop is covered by the prefix.
2908 * This would mean the via-fib, which inherits forwarding from its
2909 * cover, thus picks up forwarding from the prfix, which is via the
2910 * via-fib, and we have a loop.
2911 */
2912 fib_prefix_t pfx_23_23_23_0_s_24 = {
2913 .fp_len = 24,
2914 .fp_proto = FIB_PROTOCOL_IP4,
2915 .fp_addr = {
2916 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
2917 },
2918 };
2919 fib_prefix_t pfx_23_23_23_23_s_32 = {
2920 .fp_len = 32,
2921 .fp_proto = FIB_PROTOCOL_IP4,
2922 .fp_addr = {
2923 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
2924 },
2925 };
2926 fei = fib_table_entry_path_add(fib_index,
2927 &pfx_23_23_23_0_s_24,
2928 FIB_SOURCE_API,
2929 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002930 DPO_PROTO_IP4,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002931 &pfx_23_23_23_23_s_32.fp_addr,
2932 ~0, // recursive
2933 fib_index,
2934 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002935 NULL,
Neale Ranns3dffb1e2016-11-01 20:38:53 +00002936 FIB_ROUTE_PATH_FLAG_NONE);
2937 dpo = fib_entry_contribute_ip_forwarding(fei);
2938 FIB_TEST(load_balance_is_drop(dpo),
2939 "23.23.23.0/24 via covered is DROP");
2940 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
2941
2942 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002943 * add-remove test. no change.
2944 */
2945 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
2946 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002947 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002948 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002949 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002950 fib_entry_pool_size());
2951
2952 /*
Neale Ranns08b16482017-05-13 05:52:58 -07002953 * Make the default route recursive via a unknown next-hop. Thus the
2954 * next hop's cover would be the default route
2955 */
2956 fei = fib_table_entry_path_add(fib_index,
2957 &pfx_0_0_0_0_s_0,
2958 FIB_SOURCE_API,
2959 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002960 DPO_PROTO_IP4,
Neale Ranns08b16482017-05-13 05:52:58 -07002961 &pfx_23_23_23_23_s_32.fp_addr,
2962 ~0, // recursive
2963 fib_index,
2964 1,
2965 NULL,
2966 FIB_ROUTE_PATH_FLAG_NONE);
2967 dpo = fib_entry_contribute_ip_forwarding(fei);
2968 FIB_TEST(load_balance_is_drop(dpo),
2969 "0.0.0.0.0/0 via is DROP");
2970 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
2971 "no resolving interface for looped 0.0.0.0/0");
2972
2973 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
2974 dpo = fib_entry_contribute_ip_forwarding(fei);
2975 FIB_TEST(load_balance_is_drop(dpo),
2976 "23.23.23.23/32 via is DROP");
2977 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
2978 "no resolving interface for looped 23.23.23.23/32");
2979
2980 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
2981
2982 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002983 * A recursive route with recursion constraints.
2984 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
2985 */
2986 fib_table_entry_path_add(fib_index,
2987 &bgp_200_pfx,
2988 FIB_SOURCE_API,
2989 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002990 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002991 &nh_1_1_1_1,
2992 ~0,
2993 fib_index,
2994 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002995 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002996 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
2997
2998 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2999 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3000
3001 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3002 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3003
3004 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3005 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3006
3007 /*
3008 * save the load-balance. we expect it to be inplace modified
3009 */
3010 lb = load_balance_get(dpo1->dpoi_index);
3011
3012 /*
3013 * add a covering prefix for the via fib that would otherwise serve
3014 * as the resolving route when the host is removed
3015 */
3016 fib_table_entry_path_add(fib_index,
3017 &pfx_1_1_1_0_s_28,
3018 FIB_SOURCE_API,
3019 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003020 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003021 &nh_10_10_10_1,
3022 tm->hw[0]->sw_if_index,
3023 ~0, // invalid fib index
3024 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003025 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003026 FIB_ROUTE_PATH_FLAG_NONE);
3027 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3028 ai = fib_entry_get_adj(fei);
3029 FIB_TEST((ai == ai_01),
3030 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
3031
3032 /*
3033 * remove the host via FIB - expect the BGP prefix to be drop
3034 */
3035 fib_table_entry_path_remove(fib_index,
3036 &pfx_1_1_1_1_s_32,
3037 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003038 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003039 &nh_10_10_10_1,
3040 tm->hw[0]->sw_if_index,
3041 ~0, // invalid fib index
3042 1,
3043 FIB_ROUTE_PATH_FLAG_NONE);
3044
3045 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3046 "adj for 200.200.200.200/32 is recursive via adj for DROP");
3047
3048 /*
3049 * add the via-entry host reoute back. expect to resolve again
3050 */
3051 fib_table_entry_path_add(fib_index,
3052 &pfx_1_1_1_1_s_32,
3053 FIB_SOURCE_API,
3054 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003055 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003056 &nh_10_10_10_1,
3057 tm->hw[0]->sw_if_index,
3058 ~0, // invalid fib index
3059 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003060 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003061 FIB_ROUTE_PATH_FLAG_NONE);
3062 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
3063 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3064
3065 /*
3066 * add another path for the recursive. it will then have 2.
3067 */
3068 fib_prefix_t pfx_1_1_1_3_s_32 = {
3069 .fp_len = 32,
3070 .fp_proto = FIB_PROTOCOL_IP4,
3071 .fp_addr = {
3072 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3073 },
3074 };
3075 fib_table_entry_path_add(fib_index,
3076 &pfx_1_1_1_3_s_32,
3077 FIB_SOURCE_API,
3078 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003079 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003080 &nh_10_10_10_2,
3081 tm->hw[0]->sw_if_index,
3082 ~0, // invalid fib index
3083 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003084 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003085 FIB_ROUTE_PATH_FLAG_NONE);
3086
3087 fib_table_entry_path_add(fib_index,
3088 &bgp_200_pfx,
3089 FIB_SOURCE_API,
3090 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003091 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003092 &pfx_1_1_1_3_s_32.fp_addr,
3093 ~0,
3094 fib_index,
3095 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003096 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003097 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3098
Neale Rannsf12a83f2017-04-18 09:09:40 -07003099 /*
3100 * add a bunch load more entries using this path combo so that we get
3101 * an LB-map created.
3102 */
3103#define N_P 128
3104 fib_prefix_t bgp_78s[N_P];
3105 for (ii = 0; ii < N_P; ii++)
3106 {
3107 bgp_78s[ii].fp_len = 32;
3108 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3109 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3110
3111
3112 fib_table_entry_path_add(fib_index,
3113 &bgp_78s[ii],
3114 FIB_SOURCE_API,
3115 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003116 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003117 &pfx_1_1_1_3_s_32.fp_addr,
3118 ~0,
3119 fib_index,
3120 1,
3121 NULL,
3122 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3123 fib_table_entry_path_add(fib_index,
3124 &bgp_78s[ii],
3125 FIB_SOURCE_API,
3126 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003127 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003128 &nh_1_1_1_1,
3129 ~0,
3130 fib_index,
3131 1,
3132 NULL,
3133 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3134 }
3135
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003136 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3137 dpo = fib_entry_contribute_ip_forwarding(fei);
3138
3139 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3140 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3141 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
3142 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
3143 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3144 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3145 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
3146 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
3147
3148 /*
3149 * expect the lb-map used by the recursive's load-balance is using both buckets
3150 */
3151 load_balance_map_t *lbm;
3152 index_t lbmi;
3153
3154 lb = load_balance_get(dpo->dpoi_index);
3155 lbmi = lb->lb_map;
3156 load_balance_map_lock(lbmi);
3157 lbm = load_balance_map_get(lbmi);
3158
3159 FIB_TEST(lbm->lbm_buckets[0] == 0,
3160 "LB maps's bucket 0 is %d",
3161 lbm->lbm_buckets[0]);
3162 FIB_TEST(lbm->lbm_buckets[1] == 1,
3163 "LB maps's bucket 1 is %d",
3164 lbm->lbm_buckets[1]);
3165
3166 /*
3167 * withdraw one of the /32 via-entrys.
3168 * that ECMP path will be unresolved and forwarding should continue on the
3169 * other available path. this is an iBGP PIC edge failover.
3170 * Test the forwarding changes without re-fetching the adj from the
3171 * recursive entry. this ensures its the same one that is updated; i.e. an
3172 * inplace-modify.
3173 */
3174 fib_table_entry_path_remove(fib_index,
3175 &pfx_1_1_1_1_s_32,
3176 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003177 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003178 &nh_10_10_10_1,
3179 tm->hw[0]->sw_if_index,
3180 ~0, // invalid fib index
3181 1,
3182 FIB_ROUTE_PATH_FLAG_NONE);
3183
Neale Rannsf12a83f2017-04-18 09:09:40 -07003184 /* suspend so the update walk kicks int */
3185 vlib_process_suspend(vlib_get_main(), 1e-5);
3186
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003187 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3188 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
3189 "post PIC 200.200.200.200/32 was inplace modified");
3190
3191 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
3192 "post PIC adj for 200.200.200.200/32 is recursive"
3193 " via adj for 1.1.1.3");
3194
3195 /*
3196 * the LB maps that was locked above should have been modified to remove
3197 * the path that was down, and thus its bucket points to a path that is
3198 * still up.
3199 */
3200 FIB_TEST(lbm->lbm_buckets[0] == 1,
3201 "LB maps's bucket 0 is %d",
3202 lbm->lbm_buckets[0]);
3203 FIB_TEST(lbm->lbm_buckets[1] == 1,
3204 "LB maps's bucket 1 is %d",
3205 lbm->lbm_buckets[1]);
3206
Neale Ranns994dab42017-04-18 12:56:45 -07003207 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003208
3209 /*
3210 * add it back. again
3211 */
3212 fib_table_entry_path_add(fib_index,
3213 &pfx_1_1_1_1_s_32,
3214 FIB_SOURCE_API,
3215 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003216 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003217 &nh_10_10_10_1,
3218 tm->hw[0]->sw_if_index,
3219 ~0, // invalid fib index
3220 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003221 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003222 FIB_ROUTE_PATH_FLAG_NONE);
3223
Neale Rannsf12a83f2017-04-18 09:09:40 -07003224 /* suspend so the update walk kicks in */
3225 vlib_process_suspend(vlib_get_main(), 1e-5);
3226
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003227 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
3228 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3229 "via adj for 1.1.1.1");
3230 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
3231 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3232 "via adj for 1.1.1.3");
3233
3234 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3235 dpo = fib_entry_contribute_ip_forwarding(fei);
3236 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3237 "post PIC 200.200.200.200/32 was inplace modified");
3238
3239 /*
3240 * add a 3rd path. this makes the LB 16 buckets.
3241 */
3242 fib_table_entry_path_add(fib_index,
3243 &bgp_200_pfx,
3244 FIB_SOURCE_API,
3245 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003246 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003247 &pfx_1_1_1_2_s_32.fp_addr,
3248 ~0,
3249 fib_index,
3250 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003251 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003252 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003253 for (ii = 0; ii < N_P; ii++)
3254 {
3255 fib_table_entry_path_add(fib_index,
3256 &bgp_78s[ii],
3257 FIB_SOURCE_API,
3258 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003259 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003260 &pfx_1_1_1_2_s_32.fp_addr,
3261 ~0,
3262 fib_index,
3263 1,
3264 NULL,
3265 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3266 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003267
3268 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3269 dpo = fib_entry_contribute_ip_forwarding(fei);
3270 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3271 "200.200.200.200/32 was inplace modified for 3rd path");
3272 FIB_TEST(16 == lb->lb_n_buckets,
3273 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
3274
3275 lbmi = lb->lb_map;
3276 load_balance_map_lock(lbmi);
3277 lbm = load_balance_map_get(lbmi);
3278
3279 for (ii = 0; ii < 16; ii++)
3280 {
3281 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3282 "LB Map for 200.200.200.200/32 at %d is %d",
3283 ii, lbm->lbm_buckets[ii]);
3284 }
3285
3286 /*
3287 * trigger PIC by removing the first via-entry
3288 * the first 6 buckets of the map should map to the next 6
3289 */
3290 fib_table_entry_path_remove(fib_index,
3291 &pfx_1_1_1_1_s_32,
3292 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003293 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003294 &nh_10_10_10_1,
3295 tm->hw[0]->sw_if_index,
3296 ~0,
3297 1,
3298 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003299 /* suspend so the update walk kicks int */
3300 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003301
3302 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3303 dpo = fib_entry_contribute_ip_forwarding(fei);
3304 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
3305 "200.200.200.200/32 was inplace modified for 3rd path");
3306 FIB_TEST(2 == lb->lb_n_buckets,
3307 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
3308
3309 for (ii = 0; ii < 6; ii++)
3310 {
3311 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3312 "LB Map for 200.200.200.200/32 at %d is %d",
3313 ii, lbm->lbm_buckets[ii]);
3314 }
3315 for (ii = 6; ii < 16; ii++)
3316 {
3317 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3318 "LB Map for 200.200.200.200/32 at %d is %d",
3319 ii, lbm->lbm_buckets[ii]);
3320 }
Neale Ranns994dab42017-04-18 12:56:45 -07003321 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003322
3323 /*
3324 * tidy up
3325 */
3326 fib_table_entry_path_add(fib_index,
3327 &pfx_1_1_1_1_s_32,
3328 FIB_SOURCE_API,
3329 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003330 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003331 &nh_10_10_10_1,
3332 tm->hw[0]->sw_if_index,
3333 ~0,
3334 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003335 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003336 FIB_ROUTE_PATH_FLAG_NONE);
3337
Neale Rannsf12a83f2017-04-18 09:09:40 -07003338 for (ii = 0; ii < N_P; ii++)
3339 {
3340 fib_table_entry_delete(fib_index,
3341 &bgp_78s[ii],
3342 FIB_SOURCE_API);
3343 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3344 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3345 "%U removed",
3346 format_fib_prefix, &bgp_78s[ii]);
3347 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003348 fib_table_entry_path_remove(fib_index,
3349 &bgp_200_pfx,
3350 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003351 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003352 &pfx_1_1_1_2_s_32.fp_addr,
3353 ~0,
3354 fib_index,
3355 1,
3356 MPLS_LABEL_INVALID);
3357 fib_table_entry_path_remove(fib_index,
3358 &bgp_200_pfx,
3359 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003360 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003361 &nh_1_1_1_1,
3362 ~0,
3363 fib_index,
3364 1,
3365 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3366 fib_table_entry_path_remove(fib_index,
3367 &bgp_200_pfx,
3368 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003369 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003370 &pfx_1_1_1_3_s_32.fp_addr,
3371 ~0,
3372 fib_index,
3373 1,
3374 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3375 fib_table_entry_delete(fib_index,
3376 &pfx_1_1_1_3_s_32,
3377 FIB_SOURCE_API);
3378 fib_table_entry_delete(fib_index,
3379 &pfx_1_1_1_0_s_28,
3380 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003381 /* suspend so the update walk kicks int */
3382 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003383 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3384 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3385 "1.1.1.1/28 removed");
3386 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3387 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3388 "1.1.1.3/32 removed");
3389 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3390 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3391 "200.200.200.200/32 removed");
3392
3393 /*
3394 * add-remove test. no change.
3395 */
3396 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3397 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003398 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003399 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003400 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003401 fib_entry_pool_size());
3402
3403 /*
3404 * A route whose paths are built up iteratively and then removed
3405 * all at once
3406 */
3407 fib_prefix_t pfx_4_4_4_4_s_32 = {
3408 .fp_len = 32,
3409 .fp_proto = FIB_PROTOCOL_IP4,
3410 .fp_addr = {
3411 /* 4.4.4.4/32 */
3412 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3413 },
3414 };
3415
3416 fib_table_entry_path_add(fib_index,
3417 &pfx_4_4_4_4_s_32,
3418 FIB_SOURCE_API,
3419 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003420 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003421 &nh_10_10_10_1,
3422 tm->hw[0]->sw_if_index,
3423 ~0,
3424 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003425 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003426 FIB_ROUTE_PATH_FLAG_NONE);
3427 fib_table_entry_path_add(fib_index,
3428 &pfx_4_4_4_4_s_32,
3429 FIB_SOURCE_API,
3430 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003431 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003432 &nh_10_10_10_2,
3433 tm->hw[0]->sw_if_index,
3434 ~0,
3435 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003436 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003437 FIB_ROUTE_PATH_FLAG_NONE);
3438 fib_table_entry_path_add(fib_index,
3439 &pfx_4_4_4_4_s_32,
3440 FIB_SOURCE_API,
3441 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003442 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003443 &nh_10_10_10_3,
3444 tm->hw[0]->sw_if_index,
3445 ~0,
3446 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003447 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003448 FIB_ROUTE_PATH_FLAG_NONE);
3449 FIB_TEST(FIB_NODE_INDEX_INVALID !=
3450 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3451 "4.4.4.4/32 present");
3452
3453 fib_table_entry_delete(fib_index,
3454 &pfx_4_4_4_4_s_32,
3455 FIB_SOURCE_API);
3456 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3457 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3458 "4.4.4.4/32 removed");
3459
3460 /*
3461 * add-remove test. no change.
3462 */
3463 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3464 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003465 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003466 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003467 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003468 fib_entry_pool_size());
3469
3470 /*
3471 * A route with multiple paths at once
3472 */
3473 fib_route_path_t *r_paths = NULL;
3474
3475 for (ii = 0; ii < 4; ii++)
3476 {
3477 fib_route_path_t r_path = {
Neale Rannsda78f952017-05-24 09:15:43 -07003478 .frp_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003479 .frp_addr = {
3480 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3481 },
3482 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3483 .frp_weight = 1,
3484 .frp_fib_index = ~0,
3485 };
3486 vec_add1(r_paths, r_path);
3487 }
3488
3489 fib_table_entry_update(fib_index,
3490 &pfx_4_4_4_4_s_32,
3491 FIB_SOURCE_API,
3492 FIB_ENTRY_FLAG_NONE,
3493 r_paths);
3494
3495 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3496 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3497 dpo = fib_entry_contribute_ip_forwarding(fei);
3498
3499 lb = load_balance_get(dpo->dpoi_index);
3500 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3501
3502 fib_table_entry_delete(fib_index,
3503 &pfx_4_4_4_4_s_32,
3504 FIB_SOURCE_API);
3505 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3506 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3507 "4.4.4.4/32 removed");
3508 vec_free(r_paths);
3509
3510 /*
3511 * add-remove test. no change.
3512 */
3513 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3514 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003515 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003516 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003517 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003518 fib_entry_pool_size());
3519
3520 /*
3521 * A route deag route
3522 */
3523 fib_table_entry_path_add(fib_index,
3524 &pfx_4_4_4_4_s_32,
3525 FIB_SOURCE_API,
3526 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003527 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003528 &zero_addr,
3529 ~0,
3530 fib_index,
3531 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003532 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003533 FIB_ROUTE_PATH_FLAG_NONE);
3534
3535 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3536 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3537
3538 dpo = fib_entry_contribute_ip_forwarding(fei);
3539 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3540 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3541
3542 FIB_TEST((fib_index == lkd->lkd_fib_index),
3543 "4.4.4.4/32 is deag in %d %U",
3544 lkd->lkd_fib_index,
3545 format_dpo_id, dpo, 0);
3546
3547 fib_table_entry_delete(fib_index,
3548 &pfx_4_4_4_4_s_32,
3549 FIB_SOURCE_API);
3550 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3551 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3552 "4.4.4.4/32 removed");
3553 vec_free(r_paths);
3554
3555 /*
3556 * add-remove test. no change.
3557 */
3558 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3559 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003560 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003561 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003562 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003563 fib_entry_pool_size());
3564
3565 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003566 * Duplicate paths:
3567 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3568 */
3569 fib_prefix_t pfx_34_1_1_1_s_32 = {
3570 .fp_len = 32,
3571 .fp_proto = FIB_PROTOCOL_IP4,
3572 .fp_addr = {
3573 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3574 },
3575 };
3576 fib_prefix_t pfx_34_34_1_1_s_32 = {
3577 .fp_len = 32,
3578 .fp_proto = FIB_PROTOCOL_IP4,
3579 .fp_addr = {
3580 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3581 },
3582 };
3583 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003584 &pfx_34_34_1_1_s_32,
3585 FIB_SOURCE_API,
3586 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003587 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003588 &nh_10_10_10_1,
3589 tm->hw[0]->sw_if_index,
3590 0,
3591 1,
3592 NULL,
3593 FIB_ROUTE_PATH_FLAG_NONE);
3594 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003595 &pfx_34_1_1_1_s_32,
3596 FIB_SOURCE_API,
3597 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003598 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003599 &pfx_34_34_1_1_s_32.fp_addr,
3600 ~0,
3601 fib_index,
3602 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003603 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003604 FIB_ROUTE_PATH_FLAG_NONE);
3605 fei = fib_table_entry_path_add(fib_index,
3606 &pfx_34_1_1_1_s_32,
3607 FIB_SOURCE_API,
3608 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003609 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003610 &pfx_34_34_1_1_s_32.fp_addr,
3611 ~0,
3612 fib_index,
3613 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003614 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003615 FIB_ROUTE_PATH_FLAG_NONE);
3616 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3617 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003618 fib_table_entry_delete(fib_index,
3619 &pfx_34_34_1_1_s_32,
3620 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003621
3622 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003623 * CLEANUP
3624 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3625 * all of which are via 10.10.10.1, Itf1
3626 */
3627 fib_table_entry_path_remove(fib_index,
3628 &pfx_1_1_1_2_s_32,
3629 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003630 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003631 &nh_10_10_10_1,
3632 tm->hw[0]->sw_if_index,
3633 ~0,
3634 1,
3635 FIB_ROUTE_PATH_FLAG_NONE);
3636 fib_table_entry_path_remove(fib_index,
3637 &pfx_1_1_1_1_s_32,
3638 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003639 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003640 &nh_10_10_10_1,
3641 tm->hw[0]->sw_if_index,
3642 ~0,
3643 1,
3644 FIB_ROUTE_PATH_FLAG_NONE);
3645 fib_table_entry_path_remove(fib_index,
3646 &pfx_1_1_2_0_s_24,
3647 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07003648 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003649 &nh_10_10_10_1,
3650 tm->hw[0]->sw_if_index,
3651 ~0,
3652 1,
3653 FIB_ROUTE_PATH_FLAG_NONE);
3654
3655 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3656 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3657 "1.1.1.1/32 removed");
3658 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3659 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3660 "1.1.1.2/32 removed");
3661 FIB_TEST(FIB_NODE_INDEX_INVALID ==
3662 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3663 "1.1.2.0/24 removed");
3664
3665 /*
3666 * -3 entries and -1 shared path-list
3667 */
3668 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3669 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003670 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003671 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003672 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003673 fib_entry_pool_size());
3674
3675 /*
3676 * An attached-host route. Expect to link to the incomplete adj
3677 */
3678 fib_prefix_t pfx_4_1_1_1_s_32 = {
3679 .fp_len = 32,
3680 .fp_proto = FIB_PROTOCOL_IP4,
3681 .fp_addr = {
3682 /* 4.1.1.1/32 */
3683 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3684 },
3685 };
3686 fib_table_entry_path_add(fib_index,
3687 &pfx_4_1_1_1_s_32,
3688 FIB_SOURCE_API,
3689 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003690 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003691 &zero_addr,
3692 tm->hw[0]->sw_if_index,
3693 fib_index,
3694 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003695 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003696 FIB_ROUTE_PATH_FLAG_NONE);
3697
3698 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3699 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3700 ai = fib_entry_get_adj(fei);
3701
3702 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01003703 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003704 &pfx_4_1_1_1_s_32.fp_addr,
3705 tm->hw[0]->sw_if_index);
3706 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3707 adj_unlock(ai2);
3708
3709 /*
3710 * +1 entry and +1 shared path-list
3711 */
3712 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
3713 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003714 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003715 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003716 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003717 fib_entry_pool_size());
3718
3719 fib_table_entry_delete(fib_index,
3720 &pfx_4_1_1_1_s_32,
3721 FIB_SOURCE_API);
3722
3723 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
3724 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003725 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003726 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003727 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003728 fib_entry_pool_size());
3729
3730 /*
3731 * add a v6 prefix via v4 next-hops
3732 */
3733 fib_prefix_t pfx_2001_s_64 = {
3734 .fp_len = 64,
3735 .fp_proto = FIB_PROTOCOL_IP6,
3736 .fp_addr = {
3737 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3738 },
3739 };
3740 fei = fib_table_entry_path_add(0, //default v6 table
3741 &pfx_2001_s_64,
3742 FIB_SOURCE_API,
3743 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003744 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003745 &nh_10_10_10_1,
3746 tm->hw[0]->sw_if_index,
3747 fib_index,
3748 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003749 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003750 FIB_ROUTE_PATH_FLAG_NONE);
3751
3752 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3753 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3754 ai = fib_entry_get_adj(fei);
3755 adj = adj_get(ai);
3756 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
3757 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003758 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003759 "2001::/64 is link type v6");
3760 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
3761 "2001::/64 ADJ-adj is NH proto v4");
3762 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3763
Neale Ranns3ee44042016-10-03 13:05:48 +01003764 /*
3765 * add a uRPF exempt prefix:
3766 * test:
3767 * - it's forwarding is drop
3768 * - it's uRPF list is not empty
3769 * - the uRPF list for the default route (it's cover) is empty
3770 */
3771 fei = fib_table_entry_special_add(fib_index,
3772 &pfx_4_1_1_1_s_32,
3773 FIB_SOURCE_URPF_EXEMPT,
Neale Rannsa0558302017-04-13 00:44:52 -07003774 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003775 dpo = fib_entry_contribute_ip_forwarding(fei);
3776 FIB_TEST(load_balance_is_drop(dpo),
3777 "uRPF exempt 4.1.1.1/32 DROP");
3778 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3779 "uRPF list for exempt prefix has itf index 0");
3780 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
3781 FIB_TEST(fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3782 "uRPF list for 0.0.0.0/0 empty");
3783
3784 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003785
3786 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003787 * An adj-fib that fails the refinement criteria - no connected cover
3788 */
3789 fib_prefix_t pfx_12_10_10_2_s_32 = {
3790 .fp_len = 32,
3791 .fp_proto = FIB_PROTOCOL_IP4,
3792 .fp_addr = {
3793 /* 12.10.10.2 */
3794 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3795 },
3796 };
3797
Neale Ranns81424992017-05-18 03:03:22 -07003798 fib_table_entry_path_add(fib_index,
3799 &pfx_12_10_10_2_s_32,
3800 FIB_SOURCE_ADJ,
3801 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003802 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003803 &pfx_12_10_10_2_s_32.fp_addr,
3804 tm->hw[0]->sw_if_index,
3805 ~0, // invalid fib index
3806 1,
3807 NULL,
3808 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003809
3810 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3811 dpo = fib_entry_contribute_ip_forwarding(fei);
3812 FIB_TEST(!dpo_id_is_valid(dpo),
3813 "no connected cover adj-fib fails refinement");
3814
3815 fib_table_entry_delete(fib_index,
3816 &pfx_12_10_10_2_s_32,
3817 FIB_SOURCE_ADJ);
3818
3819 /*
3820 * An adj-fib that fails the refinement criteria - cover is connected
3821 * but on a different interface
3822 */
3823 fib_prefix_t pfx_10_10_10_127_s_32 = {
3824 .fp_len = 32,
3825 .fp_proto = FIB_PROTOCOL_IP4,
3826 .fp_addr = {
3827 /* 10.10.10.127 */
3828 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3829 },
3830 };
3831
Neale Ranns81424992017-05-18 03:03:22 -07003832 fib_table_entry_path_add(fib_index,
3833 &pfx_10_10_10_127_s_32,
3834 FIB_SOURCE_ADJ,
3835 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003836 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003837 &pfx_10_10_10_127_s_32.fp_addr,
3838 tm->hw[1]->sw_if_index,
3839 ~0, // invalid fib index
3840 1,
3841 NULL,
3842 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003843
3844 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3845 dpo = fib_entry_contribute_ip_forwarding(fei);
3846 FIB_TEST(!dpo_id_is_valid(dpo),
3847 "wrong interface adj-fib fails refinement");
3848
3849 fib_table_entry_delete(fib_index,
3850 &pfx_10_10_10_127_s_32,
3851 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07003852
3853 /*
3854 * add a second path to an adj-fib
3855 * this is a sumiluation of another ARP entry created
3856 * on an interface on which the connected prefi does not exist.
3857 * The second path fails refinement. Expect to forward through the
3858 * first.
3859 */
3860 fib_prefix_t pfx_10_10_10_3_s_32 = {
3861 .fp_len = 32,
3862 .fp_proto = FIB_PROTOCOL_IP4,
3863 .fp_addr = {
3864 /* 10.10.10.3 */
3865 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
3866 },
3867 };
3868
3869 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
3870 VNET_LINK_IP4,
3871 &nh_10_10_10_3,
3872 tm->hw[0]->sw_if_index);
3873
3874 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
3875 .type = FT_LB_ADJ,
3876 .adj = {
3877 .adj = ai_03,
3878 },
3879 };
3880 fei = fib_table_entry_path_add(fib_index,
3881 &pfx_10_10_10_3_s_32,
3882 FIB_SOURCE_ADJ,
3883 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003884 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003885 &nh_10_10_10_3,
3886 tm->hw[0]->sw_if_index,
3887 fib_index,
3888 1,
3889 NULL,
3890 FIB_ROUTE_PATH_FLAG_NONE);
3891 fei = fib_table_entry_path_add(fib_index,
3892 &pfx_10_10_10_3_s_32,
3893 FIB_SOURCE_ADJ,
3894 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003895 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003896 &nh_12_12_12_12,
3897 tm->hw[1]->sw_if_index,
3898 fib_index,
3899 1,
3900 NULL,
3901 FIB_ROUTE_PATH_FLAG_NONE);
3902 FIB_TEST(fib_test_validate_entry(fei,
3903 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
3904 1,
3905 &ip_o_10_10_10_3),
3906 "10.10.10.3 via 10.10.10.3/Eth0 only");
3907
3908 /*
3909 * remove the path that refines the cover, should go unresolved
3910 */
3911 fib_table_entry_path_remove(fib_index,
3912 &pfx_10_10_10_3_s_32,
3913 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07003914 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003915 &nh_10_10_10_3,
3916 tm->hw[0]->sw_if_index,
3917 fib_index,
3918 1,
3919 FIB_ROUTE_PATH_FLAG_NONE);
3920 dpo = fib_entry_contribute_ip_forwarding(fei);
3921 FIB_TEST(!dpo_id_is_valid(dpo),
3922 "wrong interface adj-fib fails refinement");
3923
3924 /*
3925 * add back the path that refines the cover
3926 */
3927 fei = fib_table_entry_path_add(fib_index,
3928 &pfx_10_10_10_3_s_32,
3929 FIB_SOURCE_ADJ,
3930 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003931 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003932 &nh_10_10_10_3,
3933 tm->hw[0]->sw_if_index,
3934 fib_index,
3935 1,
3936 NULL,
3937 FIB_ROUTE_PATH_FLAG_NONE);
3938 FIB_TEST(fib_test_validate_entry(fei,
3939 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
3940 1,
3941 &ip_o_10_10_10_3),
3942 "10.10.10.3 via 10.10.10.3/Eth0 only");
3943
3944 /*
3945 * remove the path that does not refine the cover
3946 */
3947 fib_table_entry_path_remove(fib_index,
3948 &pfx_10_10_10_3_s_32,
3949 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07003950 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003951 &nh_12_12_12_12,
3952 tm->hw[1]->sw_if_index,
3953 fib_index,
3954 1,
3955 FIB_ROUTE_PATH_FLAG_NONE);
3956 FIB_TEST(fib_test_validate_entry(fei,
3957 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
3958 1,
3959 &ip_o_10_10_10_3),
3960 "10.10.10.3 via 10.10.10.3/Eth0 only");
3961
3962 /*
3963 * remove the path that does refine, it's the last path, so
3964 * the entry should be gone
3965 */
3966 fib_table_entry_path_remove(fib_index,
3967 &pfx_10_10_10_3_s_32,
3968 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07003969 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003970 &nh_10_10_10_3,
3971 tm->hw[0]->sw_if_index,
3972 fib_index,
3973 1,
3974 FIB_ROUTE_PATH_FLAG_NONE);
3975 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
3976 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
3977
3978 adj_unlock(ai_03);
3979
Neale Ranns227038a2017-04-21 01:07:59 -07003980 /*
3981 * change the table's flow-hash config - expect the update to propagete to
3982 * the entries' load-balance objects
3983 */
3984 flow_hash_config_t old_hash_config, new_hash_config;
3985
3986 old_hash_config = fib_table_get_flow_hash_config(fib_index,
3987 FIB_PROTOCOL_IP4);
3988 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
3989 IP_FLOW_HASH_DST_ADDR);
3990
3991 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
3992 dpo = fib_entry_contribute_ip_forwarding(fei);
3993 lb = load_balance_get(dpo->dpoi_index);
3994 FIB_TEST((lb->lb_hash_config == old_hash_config),
3995 "Table and LB hash config match: %U",
3996 format_ip_flow_hash_config, lb->lb_hash_config);
3997
3998 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
3999
4000 FIB_TEST((lb->lb_hash_config == new_hash_config),
4001 "Table and LB newhash config match: %U",
4002 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004003
4004 /*
Neale Ranns6f631152017-10-03 08:20:21 -07004005 * A route via an L2 Bridge
4006 */
4007 fei = fib_table_entry_path_add(fib_index,
4008 &pfx_10_10_10_3_s_32,
4009 FIB_SOURCE_API,
4010 FIB_ENTRY_FLAG_NONE,
4011 DPO_PROTO_ETHERNET,
4012 &zero_addr,
4013 tm->hw[0]->sw_if_index,
4014 ~0,
4015 1,
4016 NULL,
4017 FIB_ROUTE_PATH_FLAG_NONE);
4018 dpo_id_t l2_dpo = DPO_INVALID;
4019 l2_bridge_dpo_add_or_lock(tm->hw[0]->sw_if_index, &l2_dpo);
4020 fib_test_lb_bucket_t ip_o_l2 = {
4021 .type = FT_LB_L2,
4022 .adj = {
4023 .adj = l2_dpo.dpoi_index,
4024 },
4025 };
4026
4027 FIB_TEST(fib_test_validate_entry(fei,
4028 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4029 1,
4030 &ip_o_l2),
4031 "10.10.10.3 via L2 on Eth0");
4032 fib_table_entry_path_remove(fib_index,
4033 &pfx_10_10_10_3_s_32,
4034 FIB_SOURCE_API,
4035 DPO_PROTO_ETHERNET,
4036 &zero_addr,
4037 tm->hw[0]->sw_if_index,
4038 fib_index,
4039 1,
4040 FIB_ROUTE_PATH_FLAG_NONE);
4041 dpo_reset(&l2_dpo);
4042
4043 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004044 * CLEANUP
4045 * remove adj-fibs:
4046 */
4047 fib_table_entry_delete(fib_index,
4048 &pfx_10_10_10_1_s_32,
4049 FIB_SOURCE_ADJ);
4050 fib_table_entry_delete(fib_index,
4051 &pfx_10_10_10_2_s_32,
4052 FIB_SOURCE_ADJ);
4053 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4054 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4055 "10.10.10.1/32 adj-fib removed");
4056 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4057 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4058 "10.10.10.2/32 adj-fib removed");
4059
4060 /*
4061 * -2 entries and -2 non-shared path-list
4062 */
4063 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4064 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004065 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004066 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004067 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004068 fib_entry_pool_size());
4069
4070 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004071 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004072 * These are the last locks on these adjs. they should thus go away.
4073 */
4074 adj_unlock(ai_02);
4075 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004076 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004077
4078 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4079 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004080
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004081 /*
4082 * CLEANUP
4083 * remove the interface prefixes
4084 */
4085 local_pfx.fp_len = 32;
4086 fib_table_entry_special_remove(fib_index, &local_pfx,
4087 FIB_SOURCE_INTERFACE);
4088 fei = fib_table_lookup(fib_index, &local_pfx);
4089
4090 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4091 fib_table_lookup_exact_match(fib_index, &local_pfx),
4092 "10.10.10.10/32 adj-fib removed");
4093
4094 local_pfx.fp_len = 24;
4095 fib_table_entry_delete(fib_index, &local_pfx,
4096 FIB_SOURCE_INTERFACE);
4097
4098 FIB_TEST(FIB_NODE_INDEX_INVALID ==
4099 fib_table_lookup_exact_match(fib_index, &local_pfx),
4100 "10.10.10.10/24 adj-fib removed");
4101
4102 /*
4103 * -2 entries and -2 non-shared path-list
4104 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004105 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004106 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004107 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004108 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004109 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004110 fib_entry_pool_size());
4111
4112 /*
4113 * Last but not least, remove the VRF
4114 */
4115 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4116 FIB_PROTOCOL_IP4,
4117 FIB_SOURCE_API)),
4118 "NO API Source'd prefixes");
4119 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4120 FIB_PROTOCOL_IP4,
4121 FIB_SOURCE_RR)),
4122 "NO RR Source'd prefixes");
4123 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4124 FIB_PROTOCOL_IP4,
4125 FIB_SOURCE_INTERFACE)),
4126 "NO INterface Source'd prefixes");
4127
Neale Ranns15002542017-09-10 04:39:11 -07004128 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004129
4130 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4131 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004132 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004133 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004134 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004135 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004136 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns3ee44042016-10-03 13:05:48 +01004137 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004138 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Rannsf12a83f2017-04-18 09:09:40 -07004139 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004140 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4141 pool_elts(load_balance_pool));
Neale Ranns6f631152017-10-03 08:20:21 -07004142 FIB_TEST((0 == pool_elts(l2_bridge_dpo_pool)), "L2 DPO pool size is %d",
4143 pool_elts(l2_bridge_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004144
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004145 return 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004146}
4147
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004148static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004149fib_test_v6 (void)
4150{
4151 /*
4152 * In the default table check for the presence and correct forwarding
4153 * of the special entries
4154 */
4155 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4156 const dpo_id_t *dpo, *dpo_drop;
4157 const ip_adjacency_t *adj;
4158 const receive_dpo_t *rd;
4159 test_main_t *tm;
4160 u32 fib_index;
4161 int ii;
4162
4163 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
4164 adj_nbr_db_size());
4165
4166 /* via 2001:0:0:1::2 */
4167 ip46_address_t nh_2001_2 = {
4168 .ip6 = {
4169 .as_u64 = {
4170 [0] = clib_host_to_net_u64(0x2001000000000001),
4171 [1] = clib_host_to_net_u64(0x0000000000000002),
4172 },
4173 },
4174 };
4175
4176 tm = &test_main;
4177
4178 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4179
4180 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004181 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4182 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004183
4184 for (ii = 0; ii < 4; ii++)
4185 {
4186 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
4187 }
4188
4189 fib_prefix_t pfx_0_0 = {
4190 .fp_len = 0,
4191 .fp_proto = FIB_PROTOCOL_IP6,
4192 .fp_addr = {
4193 .ip6 = {
4194 {0, 0},
4195 },
4196 },
4197 };
4198
4199 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4200 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4201 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4202 "Default route is DROP");
4203
4204 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4205 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4206 &ip6_main,
4207 1,
4208 &pfx_0_0.fp_addr.ip6)),
4209 "default-route; fwd and non-fwd tables match");
4210
4211 // FIXME - check specials.
4212
4213 /*
4214 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004215 * each with 2 entries and a v6 mfib with 4 path-lists.
4216 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004217 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004218#define ENPS (5+4)
4219#define PNPS (5+4+4)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004220 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004221 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004222 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004223 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004224 fib_entry_pool_size());
4225
4226 /*
4227 * add interface routes.
4228 * validate presence of /64 attached and /128 recieve.
4229 * test for the presence of the receive address in the glean and local adj
4230 *
4231 * receive on 2001:0:0:1::1/128
4232 */
4233 fib_prefix_t local_pfx = {
4234 .fp_len = 64,
4235 .fp_proto = FIB_PROTOCOL_IP6,
4236 .fp_addr = {
4237 .ip6 = {
4238 .as_u64 = {
4239 [0] = clib_host_to_net_u64(0x2001000000000001),
4240 [1] = clib_host_to_net_u64(0x0000000000000001),
4241 },
4242 },
4243 }
4244 };
4245
4246 fib_table_entry_update_one_path(fib_index, &local_pfx,
4247 FIB_SOURCE_INTERFACE,
4248 (FIB_ENTRY_FLAG_CONNECTED |
4249 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004250 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004251 NULL,
4252 tm->hw[0]->sw_if_index,
4253 ~0,
4254 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004255 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004256 FIB_ROUTE_PATH_FLAG_NONE);
4257 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4258
4259 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4260
4261 ai = fib_entry_get_adj(fei);
4262 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4263 adj = adj_get(ai);
4264 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4265 "attached interface adj is glean");
4266 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4267 &adj->sub_type.glean.receive_addr)),
4268 "attached interface adj is receive ok");
4269 dpo = fib_entry_contribute_ip_forwarding(fei);
4270 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4271 &ip6_main,
4272 1,
4273 &local_pfx.fp_addr.ip6)),
4274 "attached-route; fwd and non-fwd tables match");
4275
4276 local_pfx.fp_len = 128;
4277 fib_table_entry_update_one_path(fib_index, &local_pfx,
4278 FIB_SOURCE_INTERFACE,
4279 (FIB_ENTRY_FLAG_CONNECTED |
4280 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004281 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004282 NULL,
4283 tm->hw[0]->sw_if_index,
4284 ~0, // invalid fib index
4285 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004286 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004287 FIB_ROUTE_PATH_FLAG_NONE);
4288 fei = fib_table_lookup(fib_index, &local_pfx);
4289
4290 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4291
4292 dpo = fib_entry_contribute_ip_forwarding(fei);
4293 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4294 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4295 "local interface adj is local");
4296 rd = receive_dpo_get(dpo->dpoi_index);
4297
4298 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
4299 &rd->rd_addr)),
4300 "local interface adj is receive ok");
4301
4302 dpo = fib_entry_contribute_ip_forwarding(fei);
4303 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
4304 &ip6_main,
4305 1,
4306 &local_pfx.fp_addr.ip6)),
4307 "local-route; fwd and non-fwd tables match");
4308
4309 /*
4310 * +2 entries. +2 unshared path-lists
4311 */
4312 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004313 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004314 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004315 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004316 fib_entry_pool_size());
4317
4318 /*
4319 * Modify the default route to be via an adj not yet known.
4320 * this sources the defalut route with the API source, which is
4321 * a higher preference to the DEFAULT_ROUTE source
4322 */
4323 fib_table_entry_path_add(fib_index, &pfx_0_0,
4324 FIB_SOURCE_API,
4325 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004326 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004327 &nh_2001_2,
4328 tm->hw[0]->sw_if_index,
4329 ~0,
4330 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004331 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004332 FIB_ROUTE_PATH_FLAG_NONE);
4333 fei = fib_table_lookup(fib_index, &pfx_0_0);
4334
4335 FIB_TEST((fei == dfrt), "default route same index");
4336 ai = fib_entry_get_adj(fei);
4337 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4338 adj = adj_get(ai);
4339 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4340 "adj is incomplete");
4341 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
4342 "adj nbr next-hop ok");
4343
4344 /*
4345 * find the adj in the shared db
4346 */
4347 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004348 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004349 &nh_2001_2,
4350 tm->hw[0]->sw_if_index);
4351 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4352 adj_unlock(locked_ai);
4353
4354 /*
4355 * no more entires. +1 shared path-list
4356 */
4357 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4358 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004359 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004360 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004361 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004362 fib_entry_pool_size());
4363
4364 /*
4365 * remove the API source from the default route. We expected
4366 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4367 */
4368 fib_table_entry_path_remove(fib_index, &pfx_0_0,
4369 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07004370 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004371 &nh_2001_2,
4372 tm->hw[0]->sw_if_index,
4373 ~0,
4374 1,
4375 FIB_ROUTE_PATH_FLAG_NONE);
4376 fei = fib_table_lookup(fib_index, &pfx_0_0);
4377
4378 FIB_TEST((fei == dfrt), "default route same index");
4379 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
4380 "Default route is DROP");
4381
4382 /*
4383 * no more entires. -1 shared path-list
4384 */
4385 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4386 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004387 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004388 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004389 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004390 fib_entry_pool_size());
4391
4392 /*
4393 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4394 */
4395 fib_prefix_t pfx_2001_1_2_s_128 = {
4396 .fp_len = 128,
4397 .fp_proto = FIB_PROTOCOL_IP6,
4398 .fp_addr = {
4399 .ip6 = {
4400 .as_u64 = {
4401 [0] = clib_host_to_net_u64(0x2001000000000001),
4402 [1] = clib_host_to_net_u64(0x0000000000000002),
4403 },
4404 },
4405 }
4406 };
4407 fib_prefix_t pfx_2001_1_3_s_128 = {
4408 .fp_len = 128,
4409 .fp_proto = FIB_PROTOCOL_IP6,
4410 .fp_addr = {
4411 .ip6 = {
4412 .as_u64 = {
4413 [0] = clib_host_to_net_u64(0x2001000000000001),
4414 [1] = clib_host_to_net_u64(0x0000000000000003),
4415 },
4416 },
4417 }
4418 };
4419 u8 eth_addr[] = {
4420 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
4421 };
4422
4423 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004424 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004425 &pfx_2001_1_2_s_128.fp_addr,
4426 tm->hw[0]->sw_if_index);
4427 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4428 adj = adj_get(ai_01);
4429 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4430 "adj is incomplete");
4431 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4432 &adj->sub_type.nbr.next_hop)),
4433 "adj nbr next-hop ok");
4434
Neale Rannsb80c5362016-10-08 13:03:40 +01004435 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4436 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004437 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4438 "adj is complete");
4439 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
4440 &adj->sub_type.nbr.next_hop)),
4441 "adj nbr next-hop ok");
4442
Neale Ranns81424992017-05-18 03:03:22 -07004443 fib_table_entry_path_add(fib_index,
4444 &pfx_2001_1_2_s_128,
4445 FIB_SOURCE_ADJ,
4446 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004447 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004448 &pfx_2001_1_2_s_128.fp_addr,
4449 tm->hw[0]->sw_if_index,
4450 ~0,
4451 1,
4452 NULL,
4453 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004454
4455 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4456 ai = fib_entry_get_adj(fei);
4457 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4458
4459 eth_addr[5] = 0xb2;
4460
4461 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns924d03a2016-10-19 08:25:46 +01004462 VNET_LINK_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004463 &pfx_2001_1_3_s_128.fp_addr,
4464 tm->hw[0]->sw_if_index);
4465 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4466 adj = adj_get(ai_02);
4467 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
4468 "adj is incomplete");
4469 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4470 &adj->sub_type.nbr.next_hop)),
4471 "adj nbr next-hop ok");
4472
Neale Rannsb80c5362016-10-08 13:03:40 +01004473 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
4474 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004475 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
4476 "adj is complete");
4477 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
4478 &adj->sub_type.nbr.next_hop)),
4479 "adj nbr next-hop ok");
4480 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4481
Neale Ranns81424992017-05-18 03:03:22 -07004482 fib_table_entry_path_add(fib_index,
4483 &pfx_2001_1_3_s_128,
4484 FIB_SOURCE_ADJ,
4485 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004486 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004487 &pfx_2001_1_3_s_128.fp_addr,
4488 tm->hw[0]->sw_if_index,
4489 ~0,
4490 1,
4491 NULL,
4492 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004493
4494 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4495 ai = fib_entry_get_adj(fei);
4496 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4497
4498 /*
4499 * +2 entries, +2 unshread path-lists.
4500 */
4501 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4502 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004503 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004504 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004505 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004506 fib_entry_pool_size());
4507
4508 /*
4509 * Add a 2 routes via the first ADJ. ensure path-list sharing
4510 */
4511 fib_prefix_t pfx_2001_a_s_64 = {
4512 .fp_len = 64,
4513 .fp_proto = FIB_PROTOCOL_IP6,
4514 .fp_addr = {
4515 .ip6 = {
4516 .as_u64 = {
4517 [0] = clib_host_to_net_u64(0x200100000000000a),
4518 [1] = clib_host_to_net_u64(0x0000000000000000),
4519 },
4520 },
4521 }
4522 };
4523 fib_prefix_t pfx_2001_b_s_64 = {
4524 .fp_len = 64,
4525 .fp_proto = FIB_PROTOCOL_IP6,
4526 .fp_addr = {
4527 .ip6 = {
4528 .as_u64 = {
4529 [0] = clib_host_to_net_u64(0x200100000000000b),
4530 [1] = clib_host_to_net_u64(0x0000000000000000),
4531 },
4532 },
4533 }
4534 };
4535
4536 fib_table_entry_path_add(fib_index,
4537 &pfx_2001_a_s_64,
4538 FIB_SOURCE_API,
4539 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004540 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004541 &nh_2001_2,
4542 tm->hw[0]->sw_if_index,
4543 ~0,
4544 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004545 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004546 FIB_ROUTE_PATH_FLAG_NONE);
4547 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4548 ai = fib_entry_get_adj(fei);
4549 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4550 fib_table_entry_path_add(fib_index,
4551 &pfx_2001_b_s_64,
4552 FIB_SOURCE_API,
4553 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004554 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004555 &nh_2001_2,
4556 tm->hw[0]->sw_if_index,
4557 ~0,
4558 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004559 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004560 FIB_ROUTE_PATH_FLAG_NONE);
4561 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4562 ai = fib_entry_get_adj(fei);
4563 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4564
4565 /*
4566 * +2 entries, +1 shared path-list.
4567 */
4568 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4569 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004570 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004571 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004572 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004573 fib_entry_pool_size());
4574
4575 /*
4576 * add a v4 prefix via a v6 next-hop
4577 */
4578 fib_prefix_t pfx_1_1_1_1_s_32 = {
4579 .fp_len = 32,
4580 .fp_proto = FIB_PROTOCOL_IP4,
4581 .fp_addr = {
4582 .ip4.as_u32 = 0x01010101,
4583 },
4584 };
4585 fei = fib_table_entry_path_add(0, // default table
4586 &pfx_1_1_1_1_s_32,
4587 FIB_SOURCE_API,
4588 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004589 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004590 &nh_2001_2,
4591 tm->hw[0]->sw_if_index,
4592 ~0,
4593 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004594 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004595 FIB_ROUTE_PATH_FLAG_NONE);
4596 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
4597 "1.1.1.1/32 o v6 route present");
4598 ai = fib_entry_get_adj(fei);
4599 adj = adj_get(ai);
4600 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
4601 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004602 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004603 "1.1.1.1/32 ADJ-adj is link type v4");
4604 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
4605 "1.1.1.1/32 ADJ-adj is NH proto v6");
4606 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4607
4608 /*
4609 * An attached route
4610 */
4611 fib_prefix_t pfx_2001_c_s_64 = {
4612 .fp_len = 64,
4613 .fp_proto = FIB_PROTOCOL_IP6,
4614 .fp_addr = {
4615 .ip6 = {
4616 .as_u64 = {
4617 [0] = clib_host_to_net_u64(0x200100000000000c),
4618 [1] = clib_host_to_net_u64(0x0000000000000000),
4619 },
4620 },
4621 }
4622 };
4623 fib_table_entry_path_add(fib_index,
4624 &pfx_2001_c_s_64,
4625 FIB_SOURCE_CLI,
4626 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004627 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004628 NULL,
4629 tm->hw[0]->sw_if_index,
4630 ~0,
4631 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004632 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004633 FIB_ROUTE_PATH_FLAG_NONE);
4634 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4635 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4636 ai = fib_entry_get_adj(fei);
4637 adj = adj_get(ai);
4638 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
4639 "2001:0:0:c/64 attached resolves via glean");
4640
4641 fib_table_entry_path_remove(fib_index,
4642 &pfx_2001_c_s_64,
4643 FIB_SOURCE_CLI,
Neale Rannsda78f952017-05-24 09:15:43 -07004644 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004645 NULL,
4646 tm->hw[0]->sw_if_index,
4647 ~0,
4648 1,
4649 FIB_ROUTE_PATH_FLAG_NONE);
4650 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4651 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4652
4653 /*
4654 * Shutdown the interface on which we have a connected and through
4655 * which the routes are reachable.
4656 * This will result in the connected, adj-fibs, and routes linking to drop
4657 * The local/for-us prefix continues to receive.
4658 */
4659 clib_error_t * error;
4660
4661 error = vnet_sw_interface_set_flags(vnet_get_main(),
4662 tm->hw[0]->sw_if_index,
4663 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4664 FIB_TEST((NULL == error), "Interface shutdown OK");
4665
4666 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4667 dpo = fib_entry_contribute_ip_forwarding(fei);
4668 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4669 "2001::b/64 resolves via drop");
4670
4671 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4672 dpo = fib_entry_contribute_ip_forwarding(fei);
4673 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4674 "2001::a/64 resolves via drop");
4675 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4676 dpo = fib_entry_contribute_ip_forwarding(fei);
4677 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4678 "2001:0:0:1::3/64 resolves via drop");
4679 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4680 dpo = fib_entry_contribute_ip_forwarding(fei);
4681 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4682 "2001:0:0:1::2/64 resolves via drop");
4683 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4684 dpo = fib_entry_contribute_ip_forwarding(fei);
4685 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4686 "2001:0:0:1::1/128 not drop");
4687 local_pfx.fp_len = 64;
4688 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4689 dpo = fib_entry_contribute_ip_forwarding(fei);
4690 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4691 "2001:0:0:1/64 resolves via drop");
4692
4693 /*
4694 * no change
4695 */
4696 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4697 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004698 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004699 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004700 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004701 fib_entry_pool_size());
4702
4703 /*
4704 * shutdown one of the other interfaces, then add a connected.
4705 * and swap one of the routes to it.
4706 */
4707 error = vnet_sw_interface_set_flags(vnet_get_main(),
4708 tm->hw[1]->sw_if_index,
4709 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4710 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4711
4712 fib_prefix_t connected_pfx = {
4713 .fp_len = 64,
4714 .fp_proto = FIB_PROTOCOL_IP6,
4715 .fp_addr = {
4716 .ip6 = {
4717 /* 2001:0:0:2::1/64 */
4718 .as_u64 = {
4719 [0] = clib_host_to_net_u64(0x2001000000000002),
4720 [1] = clib_host_to_net_u64(0x0000000000000001),
4721 },
4722 },
4723 }
4724 };
4725 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4726 FIB_SOURCE_INTERFACE,
4727 (FIB_ENTRY_FLAG_CONNECTED |
4728 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07004729 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004730 NULL,
4731 tm->hw[1]->sw_if_index,
4732 ~0,
4733 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004734 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004735 FIB_ROUTE_PATH_FLAG_NONE);
4736 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4737 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4738 dpo = fib_entry_contribute_ip_forwarding(fei);
4739 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4740 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4741 "2001:0:0:2/64 not resolves via drop");
4742
4743 connected_pfx.fp_len = 128;
4744 fib_table_entry_update_one_path(fib_index, &connected_pfx,
4745 FIB_SOURCE_INTERFACE,
4746 (FIB_ENTRY_FLAG_CONNECTED |
4747 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07004748 DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004749 NULL,
4750 tm->hw[0]->sw_if_index,
4751 ~0, // invalid fib index
4752 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00004753 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004754 FIB_ROUTE_PATH_FLAG_NONE);
4755 fei = fib_table_lookup(fib_index, &connected_pfx);
4756
4757 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4758 dpo = fib_entry_contribute_ip_forwarding(fei);
4759 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4760 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
4761 "local interface adj is local");
4762 rd = receive_dpo_get(dpo->dpoi_index);
4763 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
4764 &rd->rd_addr)),
4765 "local interface adj is receive ok");
4766
4767 /*
4768 * +2 entries, +2 unshared path-lists
4769 */
4770 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4771 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004772 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004773 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004774 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004775 fib_entry_pool_size());
4776
4777
4778 /*
4779 * bring the interface back up. we expected the routes to return
4780 * to normal forwarding.
4781 */
4782 error = vnet_sw_interface_set_flags(vnet_get_main(),
4783 tm->hw[0]->sw_if_index,
4784 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
4785 FIB_TEST((NULL == error), "Interface bring-up OK");
4786 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4787 ai = fib_entry_get_adj(fei);
4788 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4789 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4790 ai = fib_entry_get_adj(fei);
4791 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4792 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4793 ai = fib_entry_get_adj(fei);
4794 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4795 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4796 ai = fib_entry_get_adj(fei);
4797 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4798 local_pfx.fp_len = 64;
4799 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4800 ai = fib_entry_get_adj(fei);
4801 adj = adj_get(ai);
4802 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4803 "attached interface adj is glean");
4804
4805 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004806 * Same test as above, but this time the HW interface goes down
4807 */
4808 error = vnet_hw_interface_set_flags(vnet_get_main(),
4809 tm->hw_if_indicies[0],
4810 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
4811 FIB_TEST((NULL == error), "Interface shutdown OK");
4812
4813 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4814 dpo = fib_entry_contribute_ip_forwarding(fei);
4815 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4816 "2001::b/64 resolves via drop");
4817 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4818 dpo = fib_entry_contribute_ip_forwarding(fei);
4819 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4820 "2001::a/64 resolves via drop");
4821 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4822 dpo = fib_entry_contribute_ip_forwarding(fei);
4823 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4824 "2001:0:0:1::3/128 resolves via drop");
4825 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4826 dpo = fib_entry_contribute_ip_forwarding(fei);
4827 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4828 "2001:0:0:1::2/128 resolves via drop");
4829 local_pfx.fp_len = 128;
4830 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4831 dpo = fib_entry_contribute_ip_forwarding(fei);
4832 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4833 "2001:0:0:1::1/128 not drop");
4834 local_pfx.fp_len = 64;
4835 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4836 dpo = fib_entry_contribute_ip_forwarding(fei);
4837 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
4838 "2001:0:0:1/64 resolves via drop");
4839
4840 error = vnet_hw_interface_set_flags(vnet_get_main(),
4841 tm->hw_if_indicies[0],
4842 VNET_HW_INTERFACE_FLAG_LINK_UP);
4843 FIB_TEST((NULL == error), "Interface bring-up OK");
4844 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4845 ai = fib_entry_get_adj(fei);
4846 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4847 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4848 ai = fib_entry_get_adj(fei);
4849 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4850 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4851 ai = fib_entry_get_adj(fei);
4852 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4853 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4854 ai = fib_entry_get_adj(fei);
4855 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4856 local_pfx.fp_len = 64;
4857 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4858 ai = fib_entry_get_adj(fei);
4859 adj = adj_get(ai);
4860 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
4861 "attached interface adj is glean");
4862
4863 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004864 * Delete the interface that the routes reolve through.
4865 * Again no routes are removed. They all point to drop.
4866 *
4867 * This is considered an error case. The control plane should
4868 * not remove interfaces through which routes resolve, but
4869 * such things can happen. ALL affected routes will drop.
4870 */
4871 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
4872
4873 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4874 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4875 "2001::b/64 resolves via drop");
4876 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4877 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4878 "2001::b/64 resolves via drop");
4879 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4880 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4881 "2001:0:0:1::3/64 resolves via drop");
4882 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4883 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4884 "2001:0:0:1::2/64 resolves via drop");
4885 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4886 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4887 "2001:0:0:1::1/128 is drop");
4888 local_pfx.fp_len = 64;
4889 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4890 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4891 "2001:0:0:1/64 resolves via drop");
4892
4893 /*
4894 * no change
4895 */
4896 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
4897 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004898 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004899 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004900 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004901 fib_entry_pool_size());
4902
4903 /*
4904 * Add the interface back. routes stay unresolved.
4905 */
4906 error = ethernet_register_interface(vnet_get_main(),
4907 test_interface_device_class.index,
4908 0 /* instance */,
4909 hw_address,
4910 &tm->hw_if_indicies[0],
4911 /* flag change */ 0);
4912
4913 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4914 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4915 "2001::b/64 resolves via drop");
4916 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4917 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4918 "2001::b/64 resolves via drop");
4919 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4920 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4921 "2001:0:0:1::3/64 resolves via drop");
4922 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4923 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4924 "2001:0:0:1::2/64 resolves via drop");
4925 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4926 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4927 "2001:0:0:1::1/128 is drop");
4928 local_pfx.fp_len = 64;
4929 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4930 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
4931 "2001:0:0:1/64 resolves via drop");
4932
4933 /*
4934 * CLEANUP ALL the routes
4935 */
4936 fib_table_entry_delete(fib_index,
4937 &pfx_2001_c_s_64,
4938 FIB_SOURCE_API);
4939 fib_table_entry_delete(fib_index,
4940 &pfx_2001_a_s_64,
4941 FIB_SOURCE_API);
4942 fib_table_entry_delete(fib_index,
4943 &pfx_2001_b_s_64,
4944 FIB_SOURCE_API);
4945 fib_table_entry_delete(fib_index,
4946 &pfx_2001_1_3_s_128,
4947 FIB_SOURCE_ADJ);
4948 fib_table_entry_delete(fib_index,
4949 &pfx_2001_1_2_s_128,
4950 FIB_SOURCE_ADJ);
4951 local_pfx.fp_len = 64;
4952 fib_table_entry_delete(fib_index, &local_pfx,
4953 FIB_SOURCE_INTERFACE);
4954 local_pfx.fp_len = 128;
4955 fib_table_entry_special_remove(fib_index, &local_pfx,
4956 FIB_SOURCE_INTERFACE);
4957 connected_pfx.fp_len = 64;
4958 fib_table_entry_delete(fib_index, &connected_pfx,
4959 FIB_SOURCE_INTERFACE);
4960 connected_pfx.fp_len = 128;
4961 fib_table_entry_special_remove(fib_index, &connected_pfx,
4962 FIB_SOURCE_INTERFACE);
4963
4964 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4965 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
4966 "2001::a/64 removed");
4967 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4968 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
4969 "2001::b/64 removed");
4970 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4971 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
4972 "2001:0:0:1::3/128 removed");
4973 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4974 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
4975 "2001:0:0:1::3/128 removed");
4976 local_pfx.fp_len = 64;
4977 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4978 fib_table_lookup_exact_match(fib_index, &local_pfx)),
4979 "2001:0:0:1/64 removed");
4980 local_pfx.fp_len = 128;
4981 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4982 fib_table_lookup_exact_match(fib_index, &local_pfx)),
4983 "2001:0:0:1::1/128 removed");
4984 connected_pfx.fp_len = 64;
4985 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4986 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
4987 "2001:0:0:2/64 removed");
4988 connected_pfx.fp_len = 128;
4989 FIB_TEST((FIB_NODE_INDEX_INVALID ==
4990 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
4991 "2001:0:0:2::1/128 removed");
4992
4993 /*
4994 * -8 entries. -7 path-lists (1 was shared).
4995 */
4996 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
4997 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004998 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004999 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005000 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005001 fib_entry_pool_size());
5002
5003 /*
5004 * now remove the VRF
5005 */
Neale Ranns15002542017-09-10 04:39:11 -07005006 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005007
5008 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
5009 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005010 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005011 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005012 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005013 fib_entry_pool_size());
5014
5015 adj_unlock(ai_02);
5016 adj_unlock(ai_01);
5017
5018 /*
5019 * return the interfaces to up state
5020 */
5021 error = vnet_sw_interface_set_flags(vnet_get_main(),
5022 tm->hw[0]->sw_if_index,
5023 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5024 error = vnet_sw_interface_set_flags(vnet_get_main(),
5025 tm->hw[1]->sw_if_index,
5026 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5027
5028 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5029 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005030
5031 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005032}
5033
5034/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005035 * Test Attached Exports
5036 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005037static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005038fib_test_ae (void)
5039{
5040 const dpo_id_t *dpo, *dpo_drop;
5041 const u32 fib_index = 0;
5042 fib_node_index_t fei;
5043 test_main_t *tm;
5044 ip4_main_t *im;
5045
5046 tm = &test_main;
5047 im = &ip4_main;
5048
5049 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5050 adj_nbr_db_size());
5051
5052 /*
5053 * add interface routes. We'll assume this works. It's more rigorously
5054 * tested elsewhere.
5055 */
5056 fib_prefix_t local_pfx = {
5057 .fp_len = 24,
5058 .fp_proto = FIB_PROTOCOL_IP4,
5059 .fp_addr = {
5060 .ip4 = {
5061 /* 10.10.10.10 */
5062 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5063 },
5064 },
5065 };
5066
5067 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5068 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5069
5070 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5071
5072 fib_table_entry_update_one_path(fib_index, &local_pfx,
5073 FIB_SOURCE_INTERFACE,
5074 (FIB_ENTRY_FLAG_CONNECTED |
5075 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005076 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005077 NULL,
5078 tm->hw[0]->sw_if_index,
5079 ~0,
5080 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005081 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005082 FIB_ROUTE_PATH_FLAG_NONE);
5083 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5084 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5085 "attached interface route present");
5086
5087 local_pfx.fp_len = 32;
5088 fib_table_entry_update_one_path(fib_index, &local_pfx,
5089 FIB_SOURCE_INTERFACE,
5090 (FIB_ENTRY_FLAG_CONNECTED |
5091 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07005092 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005093 NULL,
5094 tm->hw[0]->sw_if_index,
5095 ~0, // invalid fib index
5096 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005097 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005098 FIB_ROUTE_PATH_FLAG_NONE);
5099 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5100
5101 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
5102 "local interface route present");
5103
5104 /*
5105 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5106 */
5107 fib_prefix_t pfx_10_10_10_1_s_32 = {
5108 .fp_len = 32,
5109 .fp_proto = FIB_PROTOCOL_IP4,
5110 .fp_addr = {
5111 /* 10.10.10.1 */
5112 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5113 },
5114 };
5115 fib_node_index_t ai;
5116
Neale Ranns81424992017-05-18 03:03:22 -07005117 fib_table_entry_path_add(fib_index,
5118 &pfx_10_10_10_1_s_32,
5119 FIB_SOURCE_ADJ,
5120 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005121 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005122 &pfx_10_10_10_1_s_32.fp_addr,
5123 tm->hw[0]->sw_if_index,
5124 ~0, // invalid fib index
5125 1,
5126 NULL,
5127 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005128
5129 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5130 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5131 ai = fib_entry_get_adj(fei);
5132
5133 /*
5134 * create another FIB table into which routes will be imported
5135 */
5136 u32 import_fib_index1;
5137
Neale Ranns15002542017-09-10 04:39:11 -07005138 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5139 11,
5140 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005141
5142 /*
5143 * Add an attached route in the import FIB
5144 */
5145 local_pfx.fp_len = 24;
5146 fib_table_entry_update_one_path(import_fib_index1,
5147 &local_pfx,
5148 FIB_SOURCE_API,
5149 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005150 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005151 NULL,
5152 tm->hw[0]->sw_if_index,
5153 ~0, // invalid fib index
5154 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005155 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005156 FIB_ROUTE_PATH_FLAG_NONE);
5157 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5158 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5159
5160 /*
5161 * check for the presence of the adj-fibs in the import table
5162 */
5163 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5164 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5165 FIB_TEST((ai == fib_entry_get_adj(fei)),
5166 "adj-fib1 Import uses same adj as export");
5167
5168 /*
5169 * check for the presence of the local in the import table
5170 */
5171 local_pfx.fp_len = 32;
5172 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5173 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5174
5175 /*
5176 * Add another adj-fin in the export table. Expect this
5177 * to get magically exported;
5178 */
5179 fib_prefix_t pfx_10_10_10_2_s_32 = {
5180 .fp_len = 32,
5181 .fp_proto = FIB_PROTOCOL_IP4,
5182 .fp_addr = {
5183 /* 10.10.10.2 */
5184 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5185 },
5186 };
5187
Neale Ranns81424992017-05-18 03:03:22 -07005188 fib_table_entry_path_add(fib_index,
5189 &pfx_10_10_10_2_s_32,
5190 FIB_SOURCE_ADJ,
5191 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005192 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005193 &pfx_10_10_10_2_s_32.fp_addr,
5194 tm->hw[0]->sw_if_index,
5195 ~0, // invalid fib index
5196 1,
5197 NULL,
5198 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005199 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5200 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5201 ai = fib_entry_get_adj(fei);
5202
5203 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5204 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5205 FIB_TEST((ai == fib_entry_get_adj(fei)),
5206 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005207 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5208 "ADJ-fib2 imported flags %d",
5209 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005210
5211 /*
5212 * create a 2nd FIB table into which routes will be imported
5213 */
5214 u32 import_fib_index2;
5215
Neale Ranns15002542017-09-10 04:39:11 -07005216 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5217 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005218
5219 /*
5220 * Add an attached route in the import FIB
5221 */
5222 local_pfx.fp_len = 24;
5223 fib_table_entry_update_one_path(import_fib_index2,
5224 &local_pfx,
5225 FIB_SOURCE_API,
5226 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005227 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005228 NULL,
5229 tm->hw[0]->sw_if_index,
5230 ~0, // invalid fib index
5231 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005232 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005233 FIB_ROUTE_PATH_FLAG_NONE);
5234 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5235 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5236
5237 /*
5238 * check for the presence of all the adj-fibs and local in the import table
5239 */
5240 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5241 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5242 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5243 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5244 local_pfx.fp_len = 32;
5245 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5246 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5247
5248 /*
5249 * add a 3rd adj-fib. expect it to be exported to both tables.
5250 */
5251 fib_prefix_t pfx_10_10_10_3_s_32 = {
5252 .fp_len = 32,
5253 .fp_proto = FIB_PROTOCOL_IP4,
5254 .fp_addr = {
5255 /* 10.10.10.3 */
5256 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5257 },
5258 };
5259
Neale Ranns81424992017-05-18 03:03:22 -07005260 fib_table_entry_path_add(fib_index,
5261 &pfx_10_10_10_3_s_32,
5262 FIB_SOURCE_ADJ,
5263 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005264 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005265 &pfx_10_10_10_3_s_32.fp_addr,
5266 tm->hw[0]->sw_if_index,
5267 ~0, // invalid fib index
5268 1,
5269 NULL,
5270 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005271 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5272 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5273 ai = fib_entry_get_adj(fei);
5274
5275 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5276 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5277 FIB_TEST((ai == fib_entry_get_adj(fei)),
5278 "Import uses same adj as export");
5279 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5280 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5281 FIB_TEST((ai == fib_entry_get_adj(fei)),
5282 "Import uses same adj as export");
5283
5284 /*
5285 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5286 */
5287 fib_table_entry_delete(fib_index,
5288 &pfx_10_10_10_3_s_32,
5289 FIB_SOURCE_ADJ);
5290
5291 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5292 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5293
5294 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5295 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5296
5297 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5298 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5299
5300 /*
5301 * remove the attached route from the 2nd FIB. expect the imported
5302 * entires to be removed
5303 */
5304 local_pfx.fp_len = 24;
5305 fib_table_entry_delete(import_fib_index2,
5306 &local_pfx,
5307 FIB_SOURCE_API);
5308 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5309 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5310
5311 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5312 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5313 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5314 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5315 local_pfx.fp_len = 32;
5316 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5317 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5318
5319 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5320 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5321 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5322 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5323 local_pfx.fp_len = 32;
5324 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5325 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5326
5327 /*
5328 * modify the route in FIB1 so it is no longer attached. expect the imported
5329 * entires to be removed
5330 */
5331 local_pfx.fp_len = 24;
5332 fib_table_entry_update_one_path(import_fib_index1,
5333 &local_pfx,
5334 FIB_SOURCE_API,
5335 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005336 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005337 &pfx_10_10_10_2_s_32.fp_addr,
5338 tm->hw[0]->sw_if_index,
5339 ~0, // invalid fib index
5340 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005341 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005342 FIB_ROUTE_PATH_FLAG_NONE);
5343 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5344 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5345 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5346 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5347 local_pfx.fp_len = 32;
5348 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5349 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5350
5351 /*
5352 * modify it back to attached. expect the adj-fibs back
5353 */
5354 local_pfx.fp_len = 24;
5355 fib_table_entry_update_one_path(import_fib_index1,
5356 &local_pfx,
5357 FIB_SOURCE_API,
5358 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005359 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005360 NULL,
5361 tm->hw[0]->sw_if_index,
5362 ~0, // invalid fib index
5363 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005364 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005365 FIB_ROUTE_PATH_FLAG_NONE);
5366 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5367 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5368 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5369 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5370 local_pfx.fp_len = 32;
5371 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5372 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5373
5374 /*
5375 * add a covering attached next-hop for the interface address, so we have
5376 * a valid adj to find when we check the forwarding tables
5377 */
5378 fib_prefix_t pfx_10_0_0_0_s_8 = {
5379 .fp_len = 8,
5380 .fp_proto = FIB_PROTOCOL_IP4,
5381 .fp_addr = {
5382 /* 10.0.0.0 */
5383 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5384 },
5385 };
5386
5387 fei = fib_table_entry_update_one_path(fib_index,
5388 &pfx_10_0_0_0_s_8,
5389 FIB_SOURCE_API,
5390 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005391 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005392 &pfx_10_10_10_3_s_32.fp_addr,
5393 tm->hw[0]->sw_if_index,
5394 ~0, // invalid fib index
5395 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005396 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005397 FIB_ROUTE_PATH_FLAG_NONE);
5398 dpo = fib_entry_contribute_ip_forwarding(fei);
5399
5400 /*
5401 * remove the route in the export fib. expect the adj-fibs to be removed
5402 */
5403 local_pfx.fp_len = 24;
5404 fib_table_entry_delete(fib_index,
5405 &local_pfx,
5406 FIB_SOURCE_INTERFACE);
5407
5408 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5409 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5410 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5411 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5412 local_pfx.fp_len = 32;
5413 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5414 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5415
5416 /*
5417 * the adj-fibs in the export VRF are present in the FIB table,
5418 * but not installed in forwarding, since they have no attached cover.
5419 * Consequently a lookup in the MTRIE gives the adj for the covering
5420 * route 10.0.0.0/8.
5421 */
5422 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5423 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5424
5425 index_t lbi;
5426 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5427 FIB_TEST(lbi == dpo->dpoi_index,
5428 "10.10.10.1 forwards on \n%U not \n%U",
5429 format_load_balance, lbi, 0,
5430 format_dpo_id, dpo, 0);
5431 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5432 FIB_TEST(lbi == dpo->dpoi_index,
5433 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5434 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5435 FIB_TEST(lbi == dpo->dpoi_index,
5436 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5437
5438 /*
5439 * add the export prefix back, but not as attached.
5440 * No adj-fibs in export nor import tables
5441 */
5442 local_pfx.fp_len = 24;
5443 fei = fib_table_entry_update_one_path(fib_index,
5444 &local_pfx,
5445 FIB_SOURCE_API,
5446 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005447 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005448 &pfx_10_10_10_1_s_32.fp_addr,
5449 tm->hw[0]->sw_if_index,
5450 ~0, // invalid fib index
5451 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005452 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005453 FIB_ROUTE_PATH_FLAG_NONE);
5454 dpo = fib_entry_contribute_ip_forwarding(fei);
5455
5456 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5457 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5458 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5459 FIB_TEST(lbi == dpo->dpoi_index,
5460 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5461 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5462 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5463 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5464 FIB_TEST(lbi == dpo->dpoi_index,
5465 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5466
5467 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5468 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5469 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5470 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5471 local_pfx.fp_len = 32;
5472 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5473 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5474
5475 /*
5476 * modify the export prefix so it is attached. expect all covereds to return
5477 */
5478 local_pfx.fp_len = 24;
5479 fib_table_entry_update_one_path(fib_index,
5480 &local_pfx,
5481 FIB_SOURCE_API,
5482 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07005483 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005484 NULL,
5485 tm->hw[0]->sw_if_index,
5486 ~0, // invalid fib index
5487 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005488 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005489 FIB_ROUTE_PATH_FLAG_NONE);
5490
5491 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5492 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5493 dpo = fib_entry_contribute_ip_forwarding(fei);
5494 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5495 "Adj-fib1 is not drop in export");
5496 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5497 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5498 local_pfx.fp_len = 32;
5499 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5500 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5501 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5502 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5503 dpo = fib_entry_contribute_ip_forwarding(fei);
5504 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5505 "Adj-fib1 is not drop in export");
5506 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5507 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5508 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5509 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5510 local_pfx.fp_len = 32;
5511 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5512 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5513
5514 /*
5515 * modify the export prefix so connected. no change.
5516 */
5517 local_pfx.fp_len = 24;
5518 fib_table_entry_update_one_path(fib_index, &local_pfx,
5519 FIB_SOURCE_INTERFACE,
5520 (FIB_ENTRY_FLAG_CONNECTED |
5521 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07005522 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005523 NULL,
5524 tm->hw[0]->sw_if_index,
5525 ~0,
5526 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005527 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005528 FIB_ROUTE_PATH_FLAG_NONE);
5529
5530 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5531 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5532 dpo = fib_entry_contribute_ip_forwarding(fei);
5533 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5534 "Adj-fib1 is not drop in export");
5535 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5536 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5537 local_pfx.fp_len = 32;
5538 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5539 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5540 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5541 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5542 dpo = fib_entry_contribute_ip_forwarding(fei);
5543 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
5544 "Adj-fib1 is not drop in export");
5545 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5546 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5547 local_pfx.fp_len = 32;
5548 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5549 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5550
5551 /*
5552 * CLEANUP
5553 */
5554 fib_table_entry_delete(fib_index,
5555 &pfx_10_0_0_0_s_8,
5556 FIB_SOURCE_API);
5557 fib_table_entry_delete(fib_index,
5558 &pfx_10_10_10_1_s_32,
5559 FIB_SOURCE_ADJ);
5560 fib_table_entry_delete(fib_index,
5561 &pfx_10_10_10_2_s_32,
5562 FIB_SOURCE_ADJ);
5563 local_pfx.fp_len = 32;
5564 fib_table_entry_delete(fib_index,
5565 &local_pfx,
5566 FIB_SOURCE_INTERFACE);
5567 local_pfx.fp_len = 24;
5568 fib_table_entry_delete(fib_index,
5569 &local_pfx,
5570 FIB_SOURCE_API);
5571 fib_table_entry_delete(fib_index,
5572 &local_pfx,
5573 FIB_SOURCE_INTERFACE);
5574 local_pfx.fp_len = 24;
5575 fib_table_entry_delete(import_fib_index1,
5576 &local_pfx,
5577 FIB_SOURCE_API);
5578
Neale Ranns15002542017-09-10 04:39:11 -07005579 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5580 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005581
5582 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
5583 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005584
5585 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005586}
5587
Neale Ranns57b58602017-07-15 07:37:25 -07005588/*
5589 * Test Path Preference
5590 */
5591static int
5592fib_test_pref (void)
5593{
5594 test_main_t *tm = &test_main;
5595
5596 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5597 .fp_len = 32,
5598 .fp_proto = FIB_PROTOCOL_IP4,
5599 .fp_addr = {
5600 .ip4 = {
5601 .as_u32 = clib_host_to_net_u32(0x01010101),
5602 },
5603 },
5604 };
5605
5606 /*
5607 * 2 high, 2 medium and 2 low preference non-recursive paths
5608 */
5609 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005610 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005611 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5612 .frp_fib_index = ~0,
5613 .frp_weight = 1,
5614 .frp_preference = 0,
5615 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5616 .frp_addr = {
5617 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5618 },
5619 };
5620 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005621 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005622 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5623 .frp_fib_index = ~0,
5624 .frp_weight = 1,
5625 .frp_preference = 0,
5626 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5627 .frp_addr = {
5628 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5629 },
5630 };
5631 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005632 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005633 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5634 .frp_fib_index = ~0,
5635 .frp_weight = 1,
5636 .frp_preference = 1,
5637 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5638 .frp_addr = {
5639 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5640 },
5641 };
5642 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005643 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005644 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5645 .frp_fib_index = ~0,
5646 .frp_weight = 1,
5647 .frp_preference = 1,
5648 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5649 .frp_addr = {
5650 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5651 },
5652 };
5653 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005654 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005655 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5656 .frp_fib_index = ~0,
5657 .frp_weight = 1,
5658 .frp_preference = 2,
5659 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5660 .frp_addr = {
5661 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5662 },
5663 };
5664 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005665 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005666 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5667 .frp_fib_index = ~0,
5668 .frp_weight = 1,
5669 .frp_preference = 2,
5670 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5671 .frp_addr = {
5672 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5673 },
5674 };
5675 fib_route_path_t *nr_paths = NULL;
5676
5677 vec_add1(nr_paths, nr_path_hi_1);
5678 vec_add1(nr_paths, nr_path_hi_2);
5679 vec_add1(nr_paths, nr_path_med_1);
5680 vec_add1(nr_paths, nr_path_med_2);
5681 vec_add1(nr_paths, nr_path_low_1);
5682 vec_add1(nr_paths, nr_path_low_2);
5683
5684 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5685 VNET_LINK_IP4,
5686 &nr_path_hi_1.frp_addr,
5687 nr_path_hi_1.frp_sw_if_index);
5688 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5689 VNET_LINK_IP4,
5690 &nr_path_hi_2.frp_addr,
5691 nr_path_hi_2.frp_sw_if_index);
5692 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5693 VNET_LINK_IP4,
5694 &nr_path_med_1.frp_addr,
5695 nr_path_med_1.frp_sw_if_index);
5696 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5697 VNET_LINK_IP4,
5698 &nr_path_med_2.frp_addr,
5699 nr_path_med_2.frp_sw_if_index);
5700 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5701 VNET_LINK_IP4,
5702 &nr_path_low_1.frp_addr,
5703 nr_path_low_1.frp_sw_if_index);
5704 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5705 VNET_LINK_IP4,
5706 &nr_path_low_2.frp_addr,
5707 nr_path_low_2.frp_sw_if_index);
5708
5709 fib_test_lb_bucket_t ip_hi_1 = {
5710 .type = FT_LB_ADJ,
5711 .adj = {
5712 .adj = ai_hi_1,
5713 },
5714 };
5715 fib_test_lb_bucket_t ip_hi_2 = {
5716 .type = FT_LB_ADJ,
5717 .adj = {
5718 .adj = ai_hi_2,
5719 },
5720 };
5721 fib_test_lb_bucket_t ip_med_1 = {
5722 .type = FT_LB_ADJ,
5723 .adj = {
5724 .adj = ai_med_1,
5725 },
5726 };
5727 fib_test_lb_bucket_t ip_med_2 = {
5728 .type = FT_LB_ADJ,
5729 .adj = {
5730 .adj = ai_med_2,
5731 },
5732 };
5733 fib_test_lb_bucket_t ip_low_1 = {
5734 .type = FT_LB_ADJ,
5735 .adj = {
5736 .adj = ai_low_1,
5737 },
5738 };
5739 fib_test_lb_bucket_t ip_low_2 = {
5740 .type = FT_LB_ADJ,
5741 .adj = {
5742 .adj = ai_low_2,
5743 },
5744 };
5745
5746 fib_node_index_t fei;
5747
5748 fei = fib_table_entry_path_add2(0,
5749 &pfx_1_1_1_1_s_32,
5750 FIB_SOURCE_API,
5751 FIB_ENTRY_FLAG_NONE,
5752 nr_paths);
5753
5754 FIB_TEST(fib_test_validate_entry(fei,
5755 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5756 2,
5757 &ip_hi_1,
5758 &ip_hi_2),
5759 "1.1.1.1/32 via high preference paths");
5760
5761 /*
5762 * bring down the interface on which the high preference path lie
5763 */
5764 vnet_sw_interface_set_flags(vnet_get_main(),
5765 tm->hw[0]->sw_if_index,
5766 0);
5767
5768 FIB_TEST(fib_test_validate_entry(fei,
5769 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5770 2,
5771 &ip_med_1,
5772 &ip_med_2),
5773 "1.1.1.1/32 via medium preference paths");
5774
5775 /*
5776 * bring down the interface on which the medium preference path lie
5777 */
5778 vnet_sw_interface_set_flags(vnet_get_main(),
5779 tm->hw[1]->sw_if_index,
5780 0);
5781
5782 FIB_TEST(fib_test_validate_entry(fei,
5783 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5784 2,
5785 &ip_low_1,
5786 &ip_low_2),
5787 "1.1.1.1/32 via low preference paths");
5788
5789 /*
5790 * bring up the interface on which the high preference path lie
5791 */
5792 vnet_sw_interface_set_flags(vnet_get_main(),
5793 tm->hw[0]->sw_if_index,
5794 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5795
5796 FIB_TEST(fib_test_validate_entry(fei,
5797 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5798 2,
5799 &ip_hi_1,
5800 &ip_hi_2),
5801 "1.1.1.1/32 via high preference paths");
5802
5803 /*
5804 * bring up the interface on which the medium preference path lie
5805 */
5806 vnet_sw_interface_set_flags(vnet_get_main(),
5807 tm->hw[1]->sw_if_index,
5808 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5809
5810 FIB_TEST(fib_test_validate_entry(fei,
5811 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5812 2,
5813 &ip_hi_1,
5814 &ip_hi_2),
5815 "1.1.1.1/32 via high preference paths");
5816
5817 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5818 fib_entry_contribute_forwarding(fei,
5819 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5820 &ip_1_1_1_1);
5821
5822 /*
5823 * 3 recursive paths of different preference
5824 */
5825 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5826 .fp_len = 32,
5827 .fp_proto = FIB_PROTOCOL_IP4,
5828 .fp_addr = {
5829 .ip4 = {
5830 .as_u32 = clib_host_to_net_u32(0x01010102),
5831 },
5832 },
5833 };
5834 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5835 .fp_len = 32,
5836 .fp_proto = FIB_PROTOCOL_IP4,
5837 .fp_addr = {
5838 .ip4 = {
5839 .as_u32 = clib_host_to_net_u32(0x01010103),
5840 },
5841 },
5842 };
5843 fei = fib_table_entry_path_add2(0,
5844 &pfx_1_1_1_2_s_32,
5845 FIB_SOURCE_API,
5846 FIB_ENTRY_FLAG_NONE,
5847 nr_paths);
5848 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
5849 fib_entry_contribute_forwarding(fei,
5850 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5851 &ip_1_1_1_2);
5852 fei = fib_table_entry_path_add2(0,
5853 &pfx_1_1_1_3_s_32,
5854 FIB_SOURCE_API,
5855 FIB_ENTRY_FLAG_NONE,
5856 nr_paths);
5857 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
5858 fib_entry_contribute_forwarding(fei,
5859 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5860 &ip_1_1_1_3);
5861
5862 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
5863 .type = FT_LB_O_LB,
5864 .lb = {
5865 .lb = ip_1_1_1_1.dpoi_index,
5866 },
5867 };
5868 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
5869 .type = FT_LB_O_LB,
5870 .lb = {
5871 .lb = ip_1_1_1_2.dpoi_index,
5872 },
5873 };
5874 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
5875 .type = FT_LB_O_LB,
5876 .lb = {
5877 .lb = ip_1_1_1_3.dpoi_index,
5878 },
5879 };
5880 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07005881 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005882 .frp_sw_if_index = ~0,
5883 .frp_fib_index = 0,
5884 .frp_weight = 1,
5885 .frp_preference = 0,
5886 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
5887 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
5888 };
5889 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07005890 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005891 .frp_sw_if_index = ~0,
5892 .frp_fib_index = 0,
5893 .frp_weight = 1,
5894 .frp_preference = 10,
5895 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5896 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
5897 };
5898 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07005899 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005900 .frp_sw_if_index = ~0,
5901 .frp_fib_index = 0,
5902 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07005903 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07005904 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
5905 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
5906 };
5907 fib_route_path_t *r_paths = NULL;
5908
5909 vec_add1(r_paths, r_path_hi);
5910 vec_add1(r_paths, r_path_low);
5911 vec_add1(r_paths, r_path_med);
5912
5913 /*
5914 * add many recursive so we get the LB MAp created
5915 */
5916 #define N_PFXS 64
5917 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02005918 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07005919 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
5920 {
5921 pfx_r[n_pfxs].fp_len = 32;
5922 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
5923 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
5924 clib_host_to_net_u32(0x02000000 + n_pfxs);
5925
5926 fei = fib_table_entry_path_add2(0,
5927 &pfx_r[n_pfxs],
5928 FIB_SOURCE_API,
5929 FIB_ENTRY_FLAG_NONE,
5930 r_paths);
5931
5932 FIB_TEST(fib_test_validate_entry(fei,
5933 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5934 1,
5935 &ip_o_1_1_1_1),
5936 "recursive via high preference paths");
5937
5938 /*
5939 * withdraw hig pref resolving entry
5940 */
5941 fib_table_entry_delete(0,
5942 &pfx_1_1_1_1_s_32,
5943 FIB_SOURCE_API);
5944
5945 /* suspend so the update walk kicks int */
5946 vlib_process_suspend(vlib_get_main(), 1e-5);
5947
5948 FIB_TEST(fib_test_validate_entry(fei,
5949 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5950 1,
5951 &ip_o_1_1_1_2),
5952 "recursive via medium preference paths");
5953
5954 /*
5955 * withdraw medium pref resolving entry
5956 */
5957 fib_table_entry_delete(0,
5958 &pfx_1_1_1_2_s_32,
5959 FIB_SOURCE_API);
5960
5961 /* suspend so the update walk kicks int */
5962 vlib_process_suspend(vlib_get_main(), 1e-5);
5963
5964 FIB_TEST(fib_test_validate_entry(fei,
5965 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5966 1,
5967 &ip_o_1_1_1_3),
5968 "recursive via low preference paths");
5969
5970 /*
5971 * add back paths for next iteration
5972 */
5973 fei = fib_table_entry_update(0,
5974 &pfx_1_1_1_2_s_32,
5975 FIB_SOURCE_API,
5976 FIB_ENTRY_FLAG_NONE,
5977 nr_paths);
5978 fei = fib_table_entry_update(0,
5979 &pfx_1_1_1_1_s_32,
5980 FIB_SOURCE_API,
5981 FIB_ENTRY_FLAG_NONE,
5982 nr_paths);
5983
5984 /* suspend so the update walk kicks int */
5985 vlib_process_suspend(vlib_get_main(), 1e-5);
5986
5987 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
5988 FIB_TEST(fib_test_validate_entry(fei,
5989 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5990 1,
5991 &ip_o_1_1_1_1),
5992 "recursive via high preference paths");
5993 }
5994
5995
5996 fib_table_entry_delete(0,
5997 &pfx_1_1_1_1_s_32,
5998 FIB_SOURCE_API);
5999
6000 /* suspend so the update walk kicks int */
6001 vlib_process_suspend(vlib_get_main(), 1e-5);
6002
6003 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6004 {
6005 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6006
6007 FIB_TEST(fib_test_validate_entry(fei,
6008 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6009 1,
6010 &ip_o_1_1_1_2),
6011 "recursive via medium preference paths");
6012 }
6013 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6014 {
6015 fib_table_entry_delete(0,
6016 &pfx_r[n_pfxs],
6017 FIB_SOURCE_API);
6018 }
6019
6020 /*
6021 * Cleanup
6022 */
6023 fib_table_entry_delete(0,
6024 &pfx_1_1_1_2_s_32,
6025 FIB_SOURCE_API);
6026 fib_table_entry_delete(0,
6027 &pfx_1_1_1_3_s_32,
6028 FIB_SOURCE_API);
6029
6030 dpo_reset(&ip_1_1_1_1);
6031 dpo_reset(&ip_1_1_1_2);
6032 dpo_reset(&ip_1_1_1_3);
6033 adj_unlock(ai_low_2);
6034 adj_unlock(ai_low_1);
6035 adj_unlock(ai_med_2);
6036 adj_unlock(ai_med_1);
6037 adj_unlock(ai_hi_2);
6038 adj_unlock(ai_hi_1);
6039 return (0);
6040}
Neale Rannsad422ed2016-11-02 14:20:04 +00006041
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006042/*
6043 * Test the recursive route route handling for GRE tunnels
6044 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006045static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006046fib_test_label (void)
6047{
6048 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;
6049 const u32 fib_index = 0;
6050 test_main_t *tm;
6051 ip4_main_t *im;
Neale Rannsad422ed2016-11-02 14:20:04 +00006052 int lb_count, ii;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006053
6054 lb_count = pool_elts(load_balance_pool);
6055 tm = &test_main;
6056 im = &ip4_main;
6057
6058 /*
6059 * add interface routes. We'll assume this works. It's more rigorously
6060 * tested elsewhere.
6061 */
6062 fib_prefix_t local0_pfx = {
6063 .fp_len = 24,
6064 .fp_proto = FIB_PROTOCOL_IP4,
6065 .fp_addr = {
6066 .ip4 = {
6067 /* 10.10.10.10 */
6068 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6069 },
6070 },
6071 };
6072
6073 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
6074 adj_nbr_db_size());
6075
6076 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6077 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6078
6079 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6080 FIB_SOURCE_INTERFACE,
6081 (FIB_ENTRY_FLAG_CONNECTED |
6082 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006083 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006084 NULL,
6085 tm->hw[0]->sw_if_index,
6086 ~0,
6087 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006088 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006089 FIB_ROUTE_PATH_FLAG_NONE);
6090 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6091 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6092 "attached interface route present");
6093
6094 local0_pfx.fp_len = 32;
6095 fib_table_entry_update_one_path(fib_index, &local0_pfx,
6096 FIB_SOURCE_INTERFACE,
6097 (FIB_ENTRY_FLAG_CONNECTED |
6098 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006099 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006100 NULL,
6101 tm->hw[0]->sw_if_index,
6102 ~0, // invalid fib index
6103 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006104 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006105 FIB_ROUTE_PATH_FLAG_NONE);
6106 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6107
6108 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6109 "local interface route present");
6110
6111 fib_prefix_t local1_pfx = {
6112 .fp_len = 24,
6113 .fp_proto = FIB_PROTOCOL_IP4,
6114 .fp_addr = {
6115 .ip4 = {
6116 /* 10.10.11.10 */
6117 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6118 },
6119 },
6120 };
6121
6122 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6123 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6124
6125 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6126 FIB_SOURCE_INTERFACE,
6127 (FIB_ENTRY_FLAG_CONNECTED |
6128 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07006129 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006130 NULL,
6131 tm->hw[1]->sw_if_index,
6132 ~0,
6133 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006134 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006135 FIB_ROUTE_PATH_FLAG_NONE);
6136 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6137 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6138 "attached interface route present");
6139
6140 local1_pfx.fp_len = 32;
6141 fib_table_entry_update_one_path(fib_index, &local1_pfx,
6142 FIB_SOURCE_INTERFACE,
6143 (FIB_ENTRY_FLAG_CONNECTED |
6144 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07006145 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006146 NULL,
6147 tm->hw[1]->sw_if_index,
6148 ~0, // invalid fib index
6149 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006150 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006151 FIB_ROUTE_PATH_FLAG_NONE);
6152 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6153
6154 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
6155 "local interface route present");
6156
6157 ip46_address_t nh_10_10_10_1 = {
6158 .ip4 = {
6159 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6160 },
6161 };
6162 ip46_address_t nh_10_10_11_1 = {
6163 .ip4 = {
6164 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6165 },
6166 };
6167 ip46_address_t nh_10_10_11_2 = {
6168 .ip4 = {
6169 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6170 },
6171 };
6172
6173 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006174 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006175 &nh_10_10_11_1,
6176 tm->hw[1]->sw_if_index);
6177 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006178 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006179 &nh_10_10_11_2,
6180 tm->hw[1]->sw_if_index);
6181 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006182 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006183 &nh_10_10_10_1,
6184 tm->hw[0]->sw_if_index);
6185 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006186 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006187 &nh_10_10_11_2,
6188 tm->hw[1]->sw_if_index);
6189 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006190 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006191 &nh_10_10_11_1,
6192 tm->hw[1]->sw_if_index);
6193
6194 /*
6195 * Add an etry with one path with a real out-going label
6196 */
6197 fib_prefix_t pfx_1_1_1_1_s_32 = {
6198 .fp_len = 32,
6199 .fp_proto = FIB_PROTOCOL_IP4,
6200 .fp_addr = {
6201 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6202 },
6203 };
6204 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
6205 .type = FT_LB_LABEL_O_ADJ,
6206 .label_o_adj = {
6207 .adj = ai_mpls_10_10_10_1,
6208 .label = 99,
6209 .eos = MPLS_EOS,
6210 },
6211 };
6212 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
6213 .type = FT_LB_LABEL_O_ADJ,
6214 .label_o_adj = {
6215 .adj = ai_mpls_10_10_10_1,
6216 .label = 99,
6217 .eos = MPLS_NON_EOS,
6218 },
6219 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006220 mpls_label_t *l99 = NULL;
6221 vec_add1(l99, 99);
6222
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006223 fib_table_entry_update_one_path(fib_index,
6224 &pfx_1_1_1_1_s_32,
6225 FIB_SOURCE_API,
6226 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006227 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006228 &nh_10_10_10_1,
6229 tm->hw[0]->sw_if_index,
6230 ~0, // invalid fib index
6231 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006232 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006233 FIB_ROUTE_PATH_FLAG_NONE);
6234
6235 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6236 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6237
6238 FIB_TEST(fib_test_validate_entry(fei,
6239 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6240 1,
6241 &l99_eos_o_10_10_10_1),
6242 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
6243
6244 /*
6245 * add a path with an implicit NULL label
6246 */
6247 fib_test_lb_bucket_t a_o_10_10_11_1 = {
6248 .type = FT_LB_ADJ,
6249 .adj = {
6250 .adj = ai_v4_10_10_11_1,
6251 },
6252 };
6253 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
6254 .type = FT_LB_ADJ,
6255 .adj = {
6256 .adj = ai_mpls_10_10_11_1,
6257 },
6258 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006259 mpls_label_t *l_imp_null = NULL;
6260 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006261
6262 fei = fib_table_entry_path_add(fib_index,
6263 &pfx_1_1_1_1_s_32,
6264 FIB_SOURCE_API,
6265 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006266 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006267 &nh_10_10_11_1,
6268 tm->hw[1]->sw_if_index,
6269 ~0, // invalid fib index
6270 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006271 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006272 FIB_ROUTE_PATH_FLAG_NONE);
6273
6274 FIB_TEST(fib_test_validate_entry(fei,
6275 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6276 2,
6277 &l99_eos_o_10_10_10_1,
6278 &a_o_10_10_11_1),
6279 "1.1.1.1/32 LB 2 buckets via: "
6280 "label 99 over 10.10.10.1, "
6281 "adj over 10.10.11.1");
6282
6283 /*
6284 * assign the route a local label
6285 */
6286 fib_table_entry_local_label_add(fib_index,
6287 &pfx_1_1_1_1_s_32,
6288 24001);
6289
6290 fib_prefix_t pfx_24001_eos = {
6291 .fp_proto = FIB_PROTOCOL_MPLS,
6292 .fp_label = 24001,
6293 .fp_eos = MPLS_EOS,
6294 };
6295 fib_prefix_t pfx_24001_neos = {
6296 .fp_proto = FIB_PROTOCOL_MPLS,
6297 .fp_label = 24001,
6298 .fp_eos = MPLS_NON_EOS,
6299 };
6300
6301 /*
6302 * The EOS entry should link to both the paths,
6303 * and use an ip adj for the imp-null
6304 * The NON-EOS entry should link to both the paths,
6305 * and use an mpls adj for the imp-null
6306 */
6307 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6308 &pfx_24001_eos);
6309 FIB_TEST(fib_test_validate_entry(fei,
6310 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6311 2,
6312 &l99_eos_o_10_10_10_1,
6313 &a_o_10_10_11_1),
6314 "24001/eos LB 2 buckets via: "
6315 "label 99 over 10.10.10.1, "
6316 "adj over 10.10.11.1");
6317
6318
6319 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6320 &pfx_24001_neos);
6321 FIB_TEST(fib_test_validate_entry(fei,
6322 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6323 2,
6324 &l99_neos_o_10_10_10_1,
6325 &a_mpls_o_10_10_11_1),
6326 "24001/neos LB 1 bucket via: "
6327 "label 99 over 10.10.10.1 ",
6328 "mpls-adj via 10.10.11.1");
6329
6330 /*
6331 * add an unlabelled path, this is excluded from the neos chains,
6332 */
6333 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
6334 .type = FT_LB_ADJ,
6335 .adj = {
6336 .adj = ai_v4_10_10_11_2,
6337 },
6338 };
6339
6340 fei = fib_table_entry_path_add(fib_index,
6341 &pfx_1_1_1_1_s_32,
6342 FIB_SOURCE_API,
6343 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006344 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006345 &nh_10_10_11_2,
6346 tm->hw[1]->sw_if_index,
6347 ~0, // invalid fib index
6348 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006349 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006350 FIB_ROUTE_PATH_FLAG_NONE);
6351
6352 FIB_TEST(fib_test_validate_entry(fei,
6353 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6354 16, // 3 choices spread over 16 buckets
6355 &l99_eos_o_10_10_10_1,
6356 &l99_eos_o_10_10_10_1,
6357 &l99_eos_o_10_10_10_1,
6358 &l99_eos_o_10_10_10_1,
6359 &l99_eos_o_10_10_10_1,
6360 &l99_eos_o_10_10_10_1,
6361 &a_o_10_10_11_1,
6362 &a_o_10_10_11_1,
6363 &a_o_10_10_11_1,
6364 &a_o_10_10_11_1,
6365 &a_o_10_10_11_1,
6366 &adj_o_10_10_11_2,
6367 &adj_o_10_10_11_2,
6368 &adj_o_10_10_11_2,
6369 &adj_o_10_10_11_2,
6370 &adj_o_10_10_11_2),
6371 "1.1.1.1/32 LB 16 buckets via: "
6372 "label 99 over 10.10.10.1, "
6373 "adj over 10.10.11.1",
6374 "adj over 10.10.11.2");
6375
6376 /*
6377 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6378 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006379 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006380 fib_entry_contribute_forwarding(fei,
6381 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6382 &non_eos_1_1_1_1);
6383
6384 /*
6385 * n-eos has only the 2 labelled paths
6386 */
6387 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6388 &pfx_24001_neos);
6389
6390 FIB_TEST(fib_test_validate_entry(fei,
6391 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6392 2,
6393 &l99_neos_o_10_10_10_1,
6394 &a_mpls_o_10_10_11_1),
6395 "24001/neos LB 2 buckets via: "
6396 "label 99 over 10.10.10.1, "
6397 "adj-mpls over 10.10.11.2");
6398
6399 /*
6400 * A labelled recursive
6401 */
6402 fib_prefix_t pfx_2_2_2_2_s_32 = {
6403 .fp_len = 32,
6404 .fp_proto = FIB_PROTOCOL_IP4,
6405 .fp_addr = {
6406 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6407 },
6408 };
6409 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6410 .type = FT_LB_LABEL_O_LB,
6411 .label_o_lb = {
6412 .lb = non_eos_1_1_1_1.dpoi_index,
6413 .label = 1600,
6414 .eos = MPLS_EOS,
6415 },
6416 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006417 mpls_label_t *l1600 = NULL;
6418 vec_add1(l1600, 1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006419
6420 fib_table_entry_update_one_path(fib_index,
6421 &pfx_2_2_2_2_s_32,
6422 FIB_SOURCE_API,
6423 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006424 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006425 &pfx_1_1_1_1_s_32.fp_addr,
6426 ~0,
6427 fib_index,
6428 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006429 l1600,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006430 FIB_ROUTE_PATH_FLAG_NONE);
6431
6432 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
6433 FIB_TEST(fib_test_validate_entry(fei,
6434 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6435 1,
6436 &l1600_eos_o_1_1_1_1),
6437 "2.2.2.2.2/32 LB 1 buckets via: "
6438 "label 1600 over 1.1.1.1");
6439
Neale Ranns948e00f2016-10-20 13:39:34 +01006440 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006441 index_t urpfi;
6442
6443 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6444 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6445
6446 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
6447 "uRPF check for 2.2.2.2/32 on %d OK",
6448 tm->hw[0]->sw_if_index);
6449 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
6450 "uRPF check for 2.2.2.2/32 on %d OK",
6451 tm->hw[1]->sw_if_index);
6452 FIB_TEST(!fib_urpf_check(urpfi, 99),
6453 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6454 99);
6455
6456 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6457 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
6458 "Shared uRPF on IP and non-EOS chain");
6459
6460 dpo_reset(&dpo_44);
6461
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006462 /*
6463 * we are holding a lock on the non-eos LB of the via-entry.
6464 * do a PIC-core failover by shutting the link of the via-entry.
6465 *
6466 * shut down the link with the valid label
6467 */
6468 vnet_sw_interface_set_flags(vnet_get_main(),
6469 tm->hw[0]->sw_if_index,
6470 0);
6471
6472 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6473 FIB_TEST(fib_test_validate_entry(fei,
6474 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6475 2,
6476 &a_o_10_10_11_1,
6477 &adj_o_10_10_11_2),
6478 "1.1.1.1/32 LB 2 buckets via: "
6479 "adj over 10.10.11.1, ",
6480 "adj-v4 over 10.10.11.2");
6481
6482 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6483 &pfx_24001_eos);
6484 FIB_TEST(fib_test_validate_entry(fei,
6485 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6486 2,
6487 &a_o_10_10_11_1,
6488 &adj_o_10_10_11_2),
6489 "24001/eos LB 2 buckets via: "
6490 "adj over 10.10.11.1, ",
6491 "adj-v4 over 10.10.11.2");
6492
6493 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6494 &pfx_24001_neos);
6495 FIB_TEST(fib_test_validate_entry(fei,
6496 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6497 1,
6498 &a_mpls_o_10_10_11_1),
6499 "24001/neos LB 1 buckets via: "
6500 "adj-mpls over 10.10.11.2");
6501
6502 /*
6503 * test that the pre-failover load-balance has been in-place
6504 * modified
6505 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006506 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006507 fib_entry_contribute_forwarding(fei,
6508 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6509 &current);
6510
6511 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6512 &current),
6513 "PIC-core LB inplace modified %U %U",
6514 format_dpo_id, &non_eos_1_1_1_1, 0,
6515 format_dpo_id, &current, 0);
6516
6517 dpo_reset(&non_eos_1_1_1_1);
6518 dpo_reset(&current);
6519
6520 /*
6521 * no-shut the link with the valid label
6522 */
6523 vnet_sw_interface_set_flags(vnet_get_main(),
6524 tm->hw[0]->sw_if_index,
6525 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
6526
6527 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6528 FIB_TEST(fib_test_validate_entry(fei,
6529 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6530 16, // 3 choices spread over 16 buckets
6531 &l99_eos_o_10_10_10_1,
6532 &l99_eos_o_10_10_10_1,
6533 &l99_eos_o_10_10_10_1,
6534 &l99_eos_o_10_10_10_1,
6535 &l99_eos_o_10_10_10_1,
6536 &l99_eos_o_10_10_10_1,
6537 &a_o_10_10_11_1,
6538 &a_o_10_10_11_1,
6539 &a_o_10_10_11_1,
6540 &a_o_10_10_11_1,
6541 &a_o_10_10_11_1,
6542 &adj_o_10_10_11_2,
6543 &adj_o_10_10_11_2,
6544 &adj_o_10_10_11_2,
6545 &adj_o_10_10_11_2,
6546 &adj_o_10_10_11_2),
6547 "1.1.1.1/32 LB 16 buckets via: "
6548 "label 99 over 10.10.10.1, "
6549 "adj over 10.10.11.1",
6550 "adj-v4 over 10.10.11.2");
6551
6552
6553 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6554 &pfx_24001_eos);
6555 FIB_TEST(fib_test_validate_entry(fei,
6556 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6557 16, // 3 choices spread over 16 buckets
6558 &l99_eos_o_10_10_10_1,
6559 &l99_eos_o_10_10_10_1,
6560 &l99_eos_o_10_10_10_1,
6561 &l99_eos_o_10_10_10_1,
6562 &l99_eos_o_10_10_10_1,
6563 &l99_eos_o_10_10_10_1,
6564 &a_o_10_10_11_1,
6565 &a_o_10_10_11_1,
6566 &a_o_10_10_11_1,
6567 &a_o_10_10_11_1,
6568 &a_o_10_10_11_1,
6569 &adj_o_10_10_11_2,
6570 &adj_o_10_10_11_2,
6571 &adj_o_10_10_11_2,
6572 &adj_o_10_10_11_2,
6573 &adj_o_10_10_11_2),
6574 "24001/eos LB 16 buckets via: "
6575 "label 99 over 10.10.10.1, "
6576 "adj over 10.10.11.1",
6577 "adj-v4 over 10.10.11.2");
6578
6579 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6580 &pfx_24001_neos);
6581 FIB_TEST(fib_test_validate_entry(fei,
6582 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6583 2,
6584 &l99_neos_o_10_10_10_1,
6585 &a_mpls_o_10_10_11_1),
6586 "24001/neos LB 2 buckets via: "
6587 "label 99 over 10.10.10.1, "
6588 "adj-mpls over 10.10.11.2");
6589
6590 /*
6591 * remove the first path with the valid label
6592 */
6593 fib_table_entry_path_remove(fib_index,
6594 &pfx_1_1_1_1_s_32,
6595 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006596 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006597 &nh_10_10_10_1,
6598 tm->hw[0]->sw_if_index,
6599 ~0, // invalid fib index
6600 1,
6601 FIB_ROUTE_PATH_FLAG_NONE);
6602
6603 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6604 FIB_TEST(fib_test_validate_entry(fei,
6605 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6606 2,
6607 &a_o_10_10_11_1,
6608 &adj_o_10_10_11_2),
6609 "1.1.1.1/32 LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006610 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006611 "adj-v4 over 10.10.11.2");
6612
6613 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6614 &pfx_24001_eos);
6615 FIB_TEST(fib_test_validate_entry(fei,
6616 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6617 2,
6618 &a_o_10_10_11_1,
6619 &adj_o_10_10_11_2),
6620 "24001/eos LB 2 buckets via: "
Neale Rannsa3af3372017-03-28 03:49:52 -07006621 "adj over 10.10.11.1, "
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006622 "adj-v4 over 10.10.11.2");
6623
6624 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6625 &pfx_24001_neos);
6626
6627 FIB_TEST(fib_test_validate_entry(fei,
6628 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6629 1,
6630 &a_mpls_o_10_10_11_1),
6631 "24001/neos LB 1 buckets via: "
6632 "adj-mpls over 10.10.11.2");
6633
6634 /*
6635 * remove the other path with a valid label
6636 */
6637 fib_test_lb_bucket_t bucket_drop = {
6638 .type = FT_LB_SPECIAL,
6639 .special = {
Neale Ranns8fe8cc22016-11-01 10:05:08 +00006640 .adj = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006641 },
6642 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006643 fib_test_lb_bucket_t mpls_bucket_drop = {
6644 .type = FT_LB_SPECIAL,
6645 .special = {
6646 .adj = DPO_PROTO_MPLS,
6647 },
6648 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006649
6650 fib_table_entry_path_remove(fib_index,
6651 &pfx_1_1_1_1_s_32,
6652 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07006653 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006654 &nh_10_10_11_1,
6655 tm->hw[1]->sw_if_index,
6656 ~0, // invalid fib index
6657 1,
6658 FIB_ROUTE_PATH_FLAG_NONE);
6659
6660 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6661 FIB_TEST(fib_test_validate_entry(fei,
6662 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6663 1,
6664 &adj_o_10_10_11_2),
6665 "1.1.1.1/32 LB 1 buckets via: "
6666 "adj over 10.10.11.2");
6667
6668 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6669 &pfx_24001_eos);
6670 FIB_TEST(fib_test_validate_entry(fei,
6671 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6672 1,
6673 &adj_o_10_10_11_2),
6674 "24001/eos LB 1 buckets via: "
6675 "adj over 10.10.11.2");
6676
6677 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6678 &pfx_24001_neos);
6679 FIB_TEST(fib_test_validate_entry(fei,
6680 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
Neale Rannsf12a83f2017-04-18 09:09:40 -07006681 1,
6682 &mpls_bucket_drop),
6683 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006684
6685 /*
6686 * add back the path with the valid label
6687 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006688 l99 = NULL;
6689 vec_add1(l99, 99);
6690
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006691 fib_table_entry_path_add(fib_index,
6692 &pfx_1_1_1_1_s_32,
6693 FIB_SOURCE_API,
6694 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006695 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006696 &nh_10_10_10_1,
6697 tm->hw[0]->sw_if_index,
6698 ~0, // invalid fib index
6699 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006700 l99,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006701 FIB_ROUTE_PATH_FLAG_NONE);
6702
6703 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6704 FIB_TEST(fib_test_validate_entry(fei,
6705 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6706 2,
6707 &l99_eos_o_10_10_10_1,
6708 &adj_o_10_10_11_2),
6709 "1.1.1.1/32 LB 2 buckets via: "
6710 "label 99 over 10.10.10.1, "
6711 "adj over 10.10.11.2");
6712
6713 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6714 &pfx_24001_eos);
6715 FIB_TEST(fib_test_validate_entry(fei,
6716 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6717 2,
6718 &l99_eos_o_10_10_10_1,
6719 &adj_o_10_10_11_2),
6720 "24001/eos LB 2 buckets via: "
6721 "label 99 over 10.10.10.1, "
6722 "adj over 10.10.11.2");
6723
6724 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6725 &pfx_24001_neos);
6726 FIB_TEST(fib_test_validate_entry(fei,
6727 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6728 1,
6729 &l99_neos_o_10_10_10_1),
6730 "24001/neos LB 1 buckets via: "
6731 "label 99 over 10.10.10.1");
6732
6733 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006734 * change the local label
6735 */
6736 fib_table_entry_local_label_add(fib_index,
6737 &pfx_1_1_1_1_s_32,
6738 25005);
6739
6740 fib_prefix_t pfx_25005_eos = {
6741 .fp_proto = FIB_PROTOCOL_MPLS,
6742 .fp_label = 25005,
6743 .fp_eos = MPLS_EOS,
6744 };
6745 fib_prefix_t pfx_25005_neos = {
6746 .fp_proto = FIB_PROTOCOL_MPLS,
6747 .fp_label = 25005,
6748 .fp_eos = MPLS_NON_EOS,
6749 };
6750
6751 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6752 fib_table_lookup(fib_index, &pfx_24001_eos)),
6753 "24001/eos removed after label change");
6754 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6755 fib_table_lookup(fib_index, &pfx_24001_neos)),
6756 "24001/eos removed after label change");
6757
6758 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6759 &pfx_25005_eos);
6760 FIB_TEST(fib_test_validate_entry(fei,
6761 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6762 2,
6763 &l99_eos_o_10_10_10_1,
6764 &adj_o_10_10_11_2),
6765 "25005/eos LB 2 buckets via: "
6766 "label 99 over 10.10.10.1, "
6767 "adj over 10.10.11.2");
6768
6769 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
6770 &pfx_25005_neos);
6771 FIB_TEST(fib_test_validate_entry(fei,
6772 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6773 1,
6774 &l99_neos_o_10_10_10_1),
6775 "25005/neos LB 1 buckets via: "
6776 "label 99 over 10.10.10.1");
6777
6778 /*
6779 * remove the local label.
6780 * the check that the MPLS entries are gone is done by the fact the
6781 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006782 */
6783 fib_table_entry_local_label_remove(fib_index,
6784 &pfx_1_1_1_1_s_32,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006785 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006786
6787 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6788 FIB_TEST(fib_test_validate_entry(fei,
6789 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6790 2,
6791 &l99_eos_o_10_10_10_1,
6792 &adj_o_10_10_11_2),
6793 "24001/eos LB 2 buckets via: "
6794 "label 99 over 10.10.10.1, "
6795 "adj over 10.10.11.2");
6796
6797 FIB_TEST((FIB_NODE_INDEX_INVALID ==
6798 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6799 "No more MPLS FIB entries => table removed");
6800
6801 /*
6802 * add another via-entry for the recursive
6803 */
6804 fib_prefix_t pfx_1_1_1_2_s_32 = {
6805 .fp_len = 32,
6806 .fp_proto = FIB_PROTOCOL_IP4,
6807 .fp_addr = {
6808 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6809 },
6810 };
6811 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
6812 .type = FT_LB_LABEL_O_ADJ,
6813 .label_o_adj = {
6814 .adj = ai_mpls_10_10_10_1,
6815 .label = 101,
6816 .eos = MPLS_EOS,
6817 },
6818 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006819 mpls_label_t *l101 = NULL;
6820 vec_add1(l101, 101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006821
6822 fei = fib_table_entry_update_one_path(fib_index,
6823 &pfx_1_1_1_2_s_32,
6824 FIB_SOURCE_API,
6825 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006826 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006827 &nh_10_10_10_1,
6828 tm->hw[0]->sw_if_index,
6829 ~0, // invalid fib index
6830 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006831 l101,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006832 FIB_ROUTE_PATH_FLAG_NONE);
6833
6834 FIB_TEST(fib_test_validate_entry(fei,
6835 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6836 1,
6837 &l101_eos_o_10_10_10_1),
6838 "1.1.1.2/32 LB 1 buckets via: "
6839 "label 101 over 10.10.10.1");
6840
Neale Ranns948e00f2016-10-20 13:39:34 +01006841 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006842 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6843 &pfx_1_1_1_1_s_32),
6844 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6845 &non_eos_1_1_1_1);
6846 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6847 &pfx_1_1_1_2_s_32),
6848 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6849 &non_eos_1_1_1_2);
6850
6851 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
6852 .type = FT_LB_LABEL_O_LB,
6853 .label_o_lb = {
6854 .lb = non_eos_1_1_1_2.dpoi_index,
6855 .label = 1601,
6856 .eos = MPLS_EOS,
6857 },
6858 };
Neale Rannsad422ed2016-11-02 14:20:04 +00006859 mpls_label_t *l1601 = NULL;
6860 vec_add1(l1601, 1601);
6861
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006862 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
6863
6864 fei = fib_table_entry_path_add(fib_index,
6865 &pfx_2_2_2_2_s_32,
6866 FIB_SOURCE_API,
6867 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006868 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006869 &pfx_1_1_1_2_s_32.fp_addr,
6870 ~0,
6871 fib_index,
6872 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006873 l1601,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006874 FIB_ROUTE_PATH_FLAG_NONE);
6875
6876 FIB_TEST(fib_test_validate_entry(fei,
6877 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6878 2,
6879 &l1600_eos_o_1_1_1_1,
6880 &l1601_eos_o_1_1_1_2),
6881 "2.2.2.2/32 LB 2 buckets via: "
6882 "label 1600 via 1.1,1.1, "
6883 "label 16001 via 1.1.1.2");
6884
6885 /*
6886 * update the via-entry so it no longer has an imp-null path.
6887 * the LB for the recursive can use an imp-null
6888 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006889 l_imp_null = NULL;
6890 vec_add1(l_imp_null, MPLS_IETF_IMPLICIT_NULL_LABEL);
6891
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006892 fei = fib_table_entry_update_one_path(fib_index,
6893 &pfx_1_1_1_2_s_32,
6894 FIB_SOURCE_API,
6895 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006896 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006897 &nh_10_10_11_1,
6898 tm->hw[1]->sw_if_index,
6899 ~0, // invalid fib index
6900 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006901 l_imp_null,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006902 FIB_ROUTE_PATH_FLAG_NONE);
6903
6904 FIB_TEST(fib_test_validate_entry(fei,
6905 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6906 1,
6907 &a_o_10_10_11_1),
6908 "1.1.1.2/32 LB 1 buckets via: "
6909 "adj 10.10.11.1");
6910
6911 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
6912 FIB_TEST(fib_test_validate_entry(fei,
6913 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6914 2,
6915 &l1600_eos_o_1_1_1_1,
6916 &l1601_eos_o_1_1_1_2),
6917 "2.2.2.2/32 LB 2 buckets via: "
6918 "label 1600 via 1.1,1.1, "
6919 "label 16001 via 1.1.1.2");
6920
6921 /*
6922 * update the via-entry so it no longer has labelled paths.
6923 * the LB for the recursive should exclue this via form its LB
6924 */
6925 fei = fib_table_entry_update_one_path(fib_index,
6926 &pfx_1_1_1_2_s_32,
6927 FIB_SOURCE_API,
6928 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006929 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006930 &nh_10_10_11_1,
6931 tm->hw[1]->sw_if_index,
6932 ~0, // invalid fib index
6933 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006934 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006935 FIB_ROUTE_PATH_FLAG_NONE);
6936
6937 FIB_TEST(fib_test_validate_entry(fei,
6938 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6939 1,
6940 &a_o_10_10_11_1),
6941 "1.1.1.2/32 LB 1 buckets via: "
6942 "adj 10.10.11.1");
6943
6944 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
6945 FIB_TEST(fib_test_validate_entry(fei,
6946 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6947 1,
6948 &l1600_eos_o_1_1_1_1),
6949 "2.2.2.2/32 LB 1 buckets via: "
6950 "label 1600 via 1.1,1.1");
6951
6952 dpo_reset(&non_eos_1_1_1_1);
6953 dpo_reset(&non_eos_1_1_1_2);
6954
6955 /*
6956 * Add a recursive with no out-labels. We expect to use the IP of the via
6957 */
6958 fib_prefix_t pfx_2_2_2_3_s_32 = {
6959 .fp_len = 32,
6960 .fp_proto = FIB_PROTOCOL_IP4,
6961 .fp_addr = {
6962 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
6963 },
6964 };
Neale Ranns948e00f2016-10-20 13:39:34 +01006965 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006966
6967 fib_table_entry_update_one_path(fib_index,
6968 &pfx_2_2_2_3_s_32,
6969 FIB_SOURCE_API,
6970 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07006971 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006972 &pfx_1_1_1_1_s_32.fp_addr,
6973 ~0,
6974 fib_index,
6975 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00006976 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006977 FIB_ROUTE_PATH_FLAG_NONE);
6978
6979 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
6980 &pfx_1_1_1_1_s_32),
6981 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6982 &ip_1_1_1_1);
6983
6984 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
6985 .type = FT_LB_O_LB,
6986 .lb = {
6987 .lb = ip_1_1_1_1.dpoi_index,
6988 },
6989 };
6990
6991 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
6992 FIB_TEST(fib_test_validate_entry(fei,
6993 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6994 1,
6995 &ip_o_1_1_1_1),
6996 "2.2.2.2.3/32 LB 1 buckets via: "
6997 "ip 1.1.1.1");
6998
6999 /*
7000 * Add a recursive with an imp-null out-label.
7001 * We expect to use the IP of the via
7002 */
7003 fib_prefix_t pfx_2_2_2_4_s_32 = {
7004 .fp_len = 32,
7005 .fp_proto = FIB_PROTOCOL_IP4,
7006 .fp_addr = {
7007 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7008 },
7009 };
7010
7011 fib_table_entry_update_one_path(fib_index,
7012 &pfx_2_2_2_4_s_32,
7013 FIB_SOURCE_API,
7014 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007015 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007016 &pfx_1_1_1_1_s_32.fp_addr,
7017 ~0,
7018 fib_index,
7019 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00007020 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007021 FIB_ROUTE_PATH_FLAG_NONE);
7022
7023 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
7024 FIB_TEST(fib_test_validate_entry(fei,
7025 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7026 1,
7027 &ip_o_1_1_1_1),
7028 "2.2.2.2.4/32 LB 1 buckets via: "
7029 "ip 1.1.1.1");
7030
7031 dpo_reset(&ip_1_1_1_1);
7032
7033 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007034 * Create an entry with a deep label stack
7035 */
7036 fib_prefix_t pfx_2_2_5_5_s_32 = {
7037 .fp_len = 32,
7038 .fp_proto = FIB_PROTOCOL_IP4,
7039 .fp_addr = {
7040 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7041 },
7042 };
7043 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
7044 .type = FT_LB_LABEL_STACK_O_ADJ,
7045 .label_stack_o_adj = {
7046 .adj = ai_mpls_10_10_11_1,
7047 .label_stack_size = 8,
7048 .label_stack = {
7049 200, 201, 202, 203, 204, 205, 206, 207
7050 },
7051 .eos = MPLS_EOS,
7052 },
7053 };
7054 mpls_label_t *label_stack = NULL;
7055 vec_validate(label_stack, 7);
7056 for (ii = 0; ii < 8; ii++)
7057 {
7058 label_stack[ii] = ii + 200;
7059 }
7060
7061 fei = fib_table_entry_update_one_path(fib_index,
7062 &pfx_2_2_5_5_s_32,
7063 FIB_SOURCE_API,
7064 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007065 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00007066 &nh_10_10_11_1,
7067 tm->hw[1]->sw_if_index,
7068 ~0, // invalid fib index
7069 1,
7070 label_stack,
7071 FIB_ROUTE_PATH_FLAG_NONE);
7072
7073 FIB_TEST(fib_test_validate_entry(fei,
7074 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7075 1,
7076 &ls_eos_o_10_10_10_1),
7077 "2.2.5.5/32 LB 1 buckets via: "
7078 "adj 10.10.11.1");
7079 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7080
7081 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007082 * cleanup
7083 */
7084 fib_table_entry_delete(fib_index,
7085 &pfx_1_1_1_2_s_32,
7086 FIB_SOURCE_API);
7087
7088 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
7089 FIB_TEST(fib_test_validate_entry(fei,
7090 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7091 1,
7092 &l1600_eos_o_1_1_1_1),
7093 "2.2.2.2/32 LB 1 buckets via: "
7094 "label 1600 via 1.1,1.1");
7095
7096 fib_table_entry_delete(fib_index,
7097 &pfx_1_1_1_1_s_32,
7098 FIB_SOURCE_API);
7099
7100 FIB_TEST(fib_test_validate_entry(fei,
7101 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7102 1,
7103 &bucket_drop),
7104 "2.2.2.2/32 LB 1 buckets via: DROP");
7105
7106 fib_table_entry_delete(fib_index,
7107 &pfx_2_2_2_2_s_32,
7108 FIB_SOURCE_API);
7109 fib_table_entry_delete(fib_index,
7110 &pfx_2_2_2_3_s_32,
7111 FIB_SOURCE_API);
7112 fib_table_entry_delete(fib_index,
7113 &pfx_2_2_2_4_s_32,
7114 FIB_SOURCE_API);
7115
7116 adj_unlock(ai_mpls_10_10_10_1);
7117 adj_unlock(ai_mpls_10_10_11_2);
7118 adj_unlock(ai_v4_10_10_11_1);
7119 adj_unlock(ai_v4_10_10_11_2);
7120 adj_unlock(ai_mpls_10_10_11_1);
7121
7122 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
7123 adj_nbr_db_size());
7124
7125 local0_pfx.fp_len = 32;
7126 fib_table_entry_delete(fib_index,
7127 &local0_pfx,
7128 FIB_SOURCE_INTERFACE);
7129 local0_pfx.fp_len = 24;
7130 fib_table_entry_delete(fib_index,
7131 &local0_pfx,
7132 FIB_SOURCE_INTERFACE);
7133 local1_pfx.fp_len = 32;
7134 fib_table_entry_delete(fib_index,
7135 &local1_pfx,
7136 FIB_SOURCE_INTERFACE);
7137 local1_pfx.fp_len = 24;
7138 fib_table_entry_delete(fib_index,
7139 &local1_pfx,
7140 FIB_SOURCE_INTERFACE);
7141
7142 /*
7143 * +1 for the drop LB in the MPLS tables.
7144 */
7145 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
7146 "Load-balance resources freed %d of %d",
7147 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007148
7149 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007150}
7151
7152#define N_TEST_CHILDREN 4
7153#define PARENT_INDEX 0
7154
7155typedef struct fib_node_test_t_
7156{
7157 fib_node_t node;
7158 u32 sibling;
7159 u32 index;
7160 fib_node_back_walk_ctx_t *ctxs;
7161 u32 destroyed;
7162} fib_node_test_t;
7163
7164static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7165
7166#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7167
7168#define FOR_EACH_TEST_CHILD(_tc) \
7169 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7170 ii < N_TEST_CHILDREN+1; \
7171 ii++, (_tc) = &fib_test_nodes[ii])
7172
7173static fib_node_t *
7174fib_test_child_get_node (fib_node_index_t index)
7175{
7176 return (&fib_test_nodes[index].node);
7177}
7178
7179static int fib_test_walk_spawns_walks;
7180
7181static fib_node_back_walk_rc_t
7182fib_test_child_back_walk_notify (fib_node_t *node,
7183 fib_node_back_walk_ctx_t *ctx)
7184{
7185 fib_node_test_t *tc = (fib_node_test_t*) node;
7186
7187 vec_add1(tc->ctxs, *ctx);
7188
7189 if (1 == fib_test_walk_spawns_walks)
7190 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7191 if (2 == fib_test_walk_spawns_walks)
7192 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7193 FIB_WALK_PRIORITY_HIGH, ctx);
7194
7195 return (FIB_NODE_BACK_WALK_CONTINUE);
7196}
7197
7198static void
7199fib_test_child_last_lock_gone (fib_node_t *node)
7200{
7201 fib_node_test_t *tc = (fib_node_test_t *)node;
7202
7203 tc->destroyed = 1;
7204}
7205
7206/**
7207 * The FIB walk's graph node virtual function table
7208 */
7209static const fib_node_vft_t fib_test_child_vft = {
7210 .fnv_get = fib_test_child_get_node,
7211 .fnv_last_lock = fib_test_child_last_lock_gone,
7212 .fnv_back_walk = fib_test_child_back_walk_notify,
7213};
7214
7215/*
7216 * the function (that should have been static but isn't so I can do this)
7217 * that processes the walk from the async queue,
7218 */
7219f64 fib_walk_process_queues(vlib_main_t * vm,
7220 const f64 quota);
7221u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7222
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007223static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007224fib_test_walk (void)
7225{
7226 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7227 fib_node_test_t *tc;
7228 vlib_main_t *vm;
7229 u32 ii;
7230
7231 vm = vlib_get_main();
7232 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7233
7234 /*
7235 * init a fake node on which we will add children
7236 */
7237 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7238 FIB_NODE_TYPE_TEST);
7239
7240 FOR_EACH_TEST_CHILD(tc)
7241 {
7242 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7243 fib_node_lock(&tc->node);
7244 tc->ctxs = NULL;
7245 tc->index = ii;
7246 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7247 PARENT_INDEX,
7248 FIB_NODE_TYPE_TEST, ii);
7249 }
7250
7251 /*
7252 * enqueue a walk across the parents children.
7253 */
Neale Ranns450cd302016-11-09 17:49:42 +00007254 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007255
7256 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7257 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7258 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7259 "Parent has %d children pre-walk",
7260 fib_node_list_get_size(PARENT()->fn_children));
7261
7262 /*
7263 * give the walk a large amount of time so it gets to the end
7264 */
7265 fib_walk_process_queues(vm, 1);
7266
7267 FOR_EACH_TEST_CHILD(tc)
7268 {
7269 FIB_TEST(1 == vec_len(tc->ctxs),
7270 "%d child visitsed %d times",
7271 ii, vec_len(tc->ctxs));
7272 vec_free(tc->ctxs);
7273 }
7274 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7275 "Queue is empty post walk");
7276 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7277 "Parent has %d children post walk",
7278 fib_node_list_get_size(PARENT()->fn_children));
7279
7280 /*
7281 * walk again. should be no increase in the number of visits, since
7282 * the walk will have terminated.
7283 */
7284 fib_walk_process_queues(vm, 1);
7285
7286 FOR_EACH_TEST_CHILD(tc)
7287 {
7288 FIB_TEST(0 == vec_len(tc->ctxs),
7289 "%d child visitsed %d times",
7290 ii, vec_len(tc->ctxs));
7291 }
7292
7293 /*
7294 * schedule a low and hig priority walk. expect the high to be performed
7295 * before the low.
7296 * schedule the high prio walk first so that it is further from the head
7297 * of the dependency list. that way it won't merge with the low one.
7298 */
7299 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7300 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7301
7302 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7303 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7304 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7305 FIB_WALK_PRIORITY_LOW, &low_ctx);
7306
7307 fib_walk_process_queues(vm, 1);
7308
7309 FOR_EACH_TEST_CHILD(tc)
7310 {
7311 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7312 "%d child visitsed by high prio walk", ii);
7313 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7314 "%d child visitsed by low prio walk", ii);
7315 vec_free(tc->ctxs);
7316 }
7317 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7318 "Queue is empty post prio walk");
7319 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7320 "Parent has %d children post prio walk",
7321 fib_node_list_get_size(PARENT()->fn_children));
7322
7323 /*
7324 * schedule 2 walks of the same priority that can be megred.
7325 * expect that each child is thus visited only once.
7326 */
7327 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7328 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7329
7330 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7331 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7332 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7333 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7334
7335 fib_walk_process_queues(vm, 1);
7336
7337 FOR_EACH_TEST_CHILD(tc)
7338 {
7339 FIB_TEST(1 == vec_len(tc->ctxs),
7340 "%d child visitsed %d times during merge walk",
7341 ii, vec_len(tc->ctxs));
7342 vec_free(tc->ctxs);
7343 }
7344 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7345 "Queue is empty post merge walk");
7346 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7347 "Parent has %d children post merge walk",
7348 fib_node_list_get_size(PARENT()->fn_children));
7349
7350 /*
7351 * schedule 2 walks of the same priority that cannot be megred.
7352 * expect that each child is thus visited twice and in the order
7353 * in which the walks were scheduled.
7354 */
7355 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7356 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7357
7358 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7359 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7360 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7361 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7362
7363 fib_walk_process_queues(vm, 1);
7364
7365 FOR_EACH_TEST_CHILD(tc)
7366 {
7367 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7368 "%d child visitsed by high prio walk", ii);
7369 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7370 "%d child visitsed by low prio walk", ii);
7371 vec_free(tc->ctxs);
7372 }
7373 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7374 "Queue is empty post no-merge walk");
7375 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7376 "Parent has %d children post no-merge walk",
7377 fib_node_list_get_size(PARENT()->fn_children));
7378
7379 /*
7380 * schedule a walk that makes one one child progress.
7381 * we do this by giving the queue draining process zero
7382 * time quanta. it's a do..while loop, so it does something.
7383 */
Neale Ranns450cd302016-11-09 17:49:42 +00007384 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007385
7386 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7387 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7388 fib_walk_process_queues(vm, 0);
7389
7390 FOR_EACH_TEST_CHILD(tc)
7391 {
7392 if (ii == N_TEST_CHILDREN)
7393 {
7394 FIB_TEST(1 == vec_len(tc->ctxs),
7395 "%d child visitsed %d times in zero quanta walk",
7396 ii, vec_len(tc->ctxs));
7397 }
7398 else
7399 {
7400 FIB_TEST(0 == vec_len(tc->ctxs),
7401 "%d child visitsed %d times in 0 quanta walk",
7402 ii, vec_len(tc->ctxs));
7403 }
7404 }
7405 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7406 "Queue is not empty post zero quanta walk");
7407 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7408 "Parent has %d children post zero qunta walk",
7409 fib_node_list_get_size(PARENT()->fn_children));
7410
7411 /*
7412 * another one step
7413 */
7414 fib_walk_process_queues(vm, 0);
7415
7416 FOR_EACH_TEST_CHILD(tc)
7417 {
7418 if (ii >= N_TEST_CHILDREN-1)
7419 {
7420 FIB_TEST(1 == vec_len(tc->ctxs),
7421 "%d child visitsed %d times in 2nd zero quanta walk",
7422 ii, vec_len(tc->ctxs));
7423 }
7424 else
7425 {
7426 FIB_TEST(0 == vec_len(tc->ctxs),
7427 "%d child visitsed %d times in 2nd 0 quanta walk",
7428 ii, vec_len(tc->ctxs));
7429 }
7430 }
7431 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7432 "Queue is not empty post zero quanta walk");
7433 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7434 "Parent has %d children post zero qunta walk",
7435 fib_node_list_get_size(PARENT()->fn_children));
7436
7437 /*
7438 * schedule another walk that will catch-up and merge.
7439 */
7440 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7441 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7442 fib_walk_process_queues(vm, 1);
7443
7444 FOR_EACH_TEST_CHILD(tc)
7445 {
7446 if (ii >= N_TEST_CHILDREN-1)
7447 {
7448 FIB_TEST(2 == vec_len(tc->ctxs),
7449 "%d child visitsed %d times in 2nd zero quanta merge walk",
7450 ii, vec_len(tc->ctxs));
7451 vec_free(tc->ctxs);
7452 }
7453 else
7454 {
7455 FIB_TEST(1 == vec_len(tc->ctxs),
7456 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7457 ii, vec_len(tc->ctxs));
7458 vec_free(tc->ctxs);
7459 }
7460 }
7461 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7462 "Queue is not empty post 2nd zero quanta merge walk");
7463 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7464 "Parent has %d children post 2nd zero qunta merge walk",
7465 fib_node_list_get_size(PARENT()->fn_children));
7466
7467 /*
7468 * park a async walk in the middle of the list, then have an sync walk catch
7469 * it. same expectations as async catches async.
7470 */
Neale Ranns450cd302016-11-09 17:49:42 +00007471 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007472
7473 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7474 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7475
7476 fib_walk_process_queues(vm, 0);
7477 fib_walk_process_queues(vm, 0);
7478
7479 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7480
7481 FOR_EACH_TEST_CHILD(tc)
7482 {
7483 if (ii >= N_TEST_CHILDREN-1)
7484 {
7485 FIB_TEST(2 == vec_len(tc->ctxs),
7486 "%d child visitsed %d times in sync catches async walk",
7487 ii, vec_len(tc->ctxs));
7488 vec_free(tc->ctxs);
7489 }
7490 else
7491 {
7492 FIB_TEST(1 == vec_len(tc->ctxs),
7493 "%d child visitsed %d times in sync catches async walk",
7494 ii, vec_len(tc->ctxs));
7495 vec_free(tc->ctxs);
7496 }
7497 }
7498 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7499 "Queue is not empty post 2nd zero quanta merge walk");
7500 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7501 "Parent has %d children post 2nd zero qunta merge walk",
7502 fib_node_list_get_size(PARENT()->fn_children));
7503
7504 /*
7505 * make the parent a child of one of its children, thus inducing a routing loop.
7506 */
7507 fib_test_nodes[PARENT_INDEX].sibling =
7508 fib_node_child_add(FIB_NODE_TYPE_TEST,
7509 1, // the first child
7510 FIB_NODE_TYPE_TEST,
7511 PARENT_INDEX);
7512
7513 /*
7514 * execute a sync walk from the parent. each child visited spawns more sync
7515 * walks. we expect the walk to terminate.
7516 */
7517 fib_test_walk_spawns_walks = 1;
7518
7519 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7520
7521 FOR_EACH_TEST_CHILD(tc)
7522 {
7523 /*
7524 * child 1 - which is last in the list - has the loop.
7525 * the other children a re thus visitsed first. the we meet
7526 * child 1. we go round the loop again, visting the other children.
7527 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7528 * again.
7529 */
7530 if (1 == ii)
7531 {
7532 FIB_TEST(1 == vec_len(tc->ctxs),
7533 "child %d visitsed %d times during looped sync walk",
7534 ii, vec_len(tc->ctxs));
7535 }
7536 else
7537 {
7538 FIB_TEST(2 == vec_len(tc->ctxs),
7539 "child %d visitsed %d times during looped sync walk",
7540 ii, vec_len(tc->ctxs));
7541 }
7542 vec_free(tc->ctxs);
7543 }
7544 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7545 "Parent has %d children post sync loop walk",
7546 fib_node_list_get_size(PARENT()->fn_children));
7547
7548 /*
7549 * the walk doesn't reach the max depth because the infra knows that sync
7550 * meets sync implies a loop and bails early.
7551 */
7552 FIB_TEST(high_ctx.fnbw_depth == 9,
7553 "Walk context depth %d post sync loop walk",
7554 high_ctx.fnbw_depth);
7555
7556 /*
7557 * execute an async walk of the graph loop, with each child spawns sync walks
7558 */
7559 high_ctx.fnbw_depth = 0;
7560 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7561 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7562
7563 fib_walk_process_queues(vm, 1);
7564
7565 FOR_EACH_TEST_CHILD(tc)
7566 {
7567 /*
7568 * we don't really care how many times the children are visisted, as long as
7569 * it is more than once.
7570 */
7571 FIB_TEST(1 <= vec_len(tc->ctxs),
7572 "child %d visitsed %d times during looped aync spawns sync walk",
7573 ii, vec_len(tc->ctxs));
7574 vec_free(tc->ctxs);
7575 }
7576
7577 /*
7578 * execute an async walk of the graph loop, with each child spawns async walks
7579 */
7580 fib_test_walk_spawns_walks = 2;
7581 high_ctx.fnbw_depth = 0;
7582 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7583 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7584
7585 fib_walk_process_queues(vm, 1);
7586
7587 FOR_EACH_TEST_CHILD(tc)
7588 {
7589 /*
7590 * we don't really care how many times the children are visisted, as long as
7591 * it is more than once.
7592 */
7593 FIB_TEST(1 <= vec_len(tc->ctxs),
7594 "child %d visitsed %d times during looped async spawns async walk",
7595 ii, vec_len(tc->ctxs));
7596 vec_free(tc->ctxs);
7597 }
7598
7599
7600 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7601 1, // the first child
7602 fib_test_nodes[PARENT_INDEX].sibling);
7603
7604 /*
7605 * cleanup
7606 */
7607 FOR_EACH_TEST_CHILD(tc)
7608 {
7609 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7610 tc->sibling);
7611 fib_node_deinit(&tc->node);
7612 fib_node_unlock(&tc->node);
7613 }
7614 fib_node_deinit(PARENT());
7615
7616 /*
7617 * The parent will be destroyed when the last lock on it goes.
7618 * this test ensures all the walk objects are unlocking it.
7619 */
7620 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7621 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007622
7623 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007624}
7625
Neale Ranns88fc83e2017-04-05 08:11:14 -07007626/*
7627 * declaration of the otherwise static callback functions
7628 */
7629void fib_bfd_notify (bfd_listen_event_e event,
7630 const bfd_session_t *session);
7631void adj_bfd_notify (bfd_listen_event_e event,
7632 const bfd_session_t *session);
7633
7634/**
7635 * Test BFD session interaction with FIB
7636 */
7637static int
7638fib_test_bfd (void)
7639{
7640 fib_node_index_t fei;
7641 test_main_t *tm;
7642 int n_feis;
7643
7644 /* via 10.10.10.1 */
7645 ip46_address_t nh_10_10_10_1 = {
7646 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7647 };
7648 /* via 10.10.10.2 */
7649 ip46_address_t nh_10_10_10_2 = {
7650 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7651 };
7652 /* via 10.10.10.10 */
7653 ip46_address_t nh_10_10_10_10 = {
7654 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7655 };
7656 n_feis = fib_entry_pool_size();
7657
7658 tm = &test_main;
7659
7660 /*
7661 * add interface routes. we'll assume this works. it's tested elsewhere
7662 */
7663 fib_prefix_t pfx_10_10_10_10_s_24 = {
7664 .fp_len = 24,
7665 .fp_proto = FIB_PROTOCOL_IP4,
7666 .fp_addr = nh_10_10_10_10,
7667 };
7668
7669 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7670 FIB_SOURCE_INTERFACE,
7671 (FIB_ENTRY_FLAG_CONNECTED |
7672 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007673 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007674 NULL,
7675 tm->hw[0]->sw_if_index,
7676 ~0, // invalid fib index
7677 1, // weight
7678 NULL,
7679 FIB_ROUTE_PATH_FLAG_NONE);
7680
7681 fib_prefix_t pfx_10_10_10_10_s_32 = {
7682 .fp_len = 32,
7683 .fp_proto = FIB_PROTOCOL_IP4,
7684 .fp_addr = nh_10_10_10_10,
7685 };
7686 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7687 FIB_SOURCE_INTERFACE,
7688 (FIB_ENTRY_FLAG_CONNECTED |
7689 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007690 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007691 NULL,
7692 tm->hw[0]->sw_if_index,
7693 ~0, // invalid fib index
7694 1, // weight
7695 NULL,
7696 FIB_ROUTE_PATH_FLAG_NONE);
7697
7698 /*
7699 * A BFD session via a neighbour we do not yet know
7700 */
7701 bfd_session_t bfd_10_10_10_1 = {
7702 .udp = {
7703 .key = {
7704 .fib_index = 0,
7705 .peer_addr = nh_10_10_10_1,
7706 },
7707 },
7708 .hop_type = BFD_HOP_TYPE_MULTI,
7709 .local_state = BFD_STATE_init,
7710 };
7711
7712 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7713
7714 /*
7715 * A new entry will be created that forwards via the adj
7716 */
7717 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7718 VNET_LINK_IP4,
7719 &nh_10_10_10_1,
7720 tm->hw[0]->sw_if_index);
7721 fib_prefix_t pfx_10_10_10_1_s_32 = {
7722 .fp_addr = nh_10_10_10_1,
7723 .fp_len = 32,
7724 .fp_proto = FIB_PROTOCOL_IP4,
7725 };
7726 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7727 .type = FT_LB_ADJ,
7728 .adj = {
7729 .adj = ai_10_10_10_1,
7730 },
7731 };
7732
7733 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7734 FIB_TEST(fib_test_validate_entry(fei,
7735 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7736 1,
7737 &adj_o_10_10_10_1),
7738 "BFD sourced %U via %U",
7739 format_fib_prefix, &pfx_10_10_10_1_s_32,
7740 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7741
7742 /*
7743 * Delete the BFD session. Expect the fib_entry to be removed
7744 */
7745 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7746
7747 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7748 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7749 "BFD sourced %U removed",
7750 format_fib_prefix, &pfx_10_10_10_1_s_32);
7751
7752 /*
7753 * Add the BFD source back
7754 */
7755 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7756
7757 /*
7758 * source the entry via the ADJ fib
7759 */
Neale Ranns81424992017-05-18 03:03:22 -07007760 fei = fib_table_entry_path_add(0,
7761 &pfx_10_10_10_1_s_32,
7762 FIB_SOURCE_ADJ,
7763 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007764 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007765 &nh_10_10_10_1,
7766 tm->hw[0]->sw_if_index,
7767 ~0, // invalid fib index
7768 1,
7769 NULL,
7770 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007771
7772 /*
7773 * Delete the BFD session. Expect the fib_entry to remain
7774 */
7775 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7776
7777 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7778 FIB_TEST(fib_test_validate_entry(fei,
7779 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7780 1,
7781 &adj_o_10_10_10_1),
7782 "BFD sourced %U remains via %U",
7783 format_fib_prefix, &pfx_10_10_10_1_s_32,
7784 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7785
7786 /*
7787 * Add the BFD source back
7788 */
7789 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7790
7791 /*
7792 * Create another ADJ FIB
7793 */
7794 fib_prefix_t pfx_10_10_10_2_s_32 = {
7795 .fp_addr = nh_10_10_10_2,
7796 .fp_len = 32,
7797 .fp_proto = FIB_PROTOCOL_IP4,
7798 };
Neale Ranns81424992017-05-18 03:03:22 -07007799 fib_table_entry_path_add(0,
7800 &pfx_10_10_10_2_s_32,
7801 FIB_SOURCE_ADJ,
7802 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007803 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007804 &nh_10_10_10_2,
7805 tm->hw[0]->sw_if_index,
7806 ~0, // invalid fib index
7807 1,
7808 NULL,
7809 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007810 /*
7811 * A BFD session for the new ADJ FIB
7812 */
7813 bfd_session_t bfd_10_10_10_2 = {
7814 .udp = {
7815 .key = {
7816 .fib_index = 0,
7817 .peer_addr = nh_10_10_10_2,
7818 },
7819 },
7820 .hop_type = BFD_HOP_TYPE_MULTI,
7821 .local_state = BFD_STATE_init,
7822 };
7823
7824 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
7825
7826 /*
7827 * remove the adj-fib source whilst the session is present
7828 * then add it back
7829 */
7830 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07007831 fib_table_entry_path_add(0,
7832 &pfx_10_10_10_2_s_32,
7833 FIB_SOURCE_ADJ,
7834 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007835 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007836 &nh_10_10_10_2,
7837 tm->hw[0]->sw_if_index,
7838 ~0, // invalid fib index
7839 1,
7840 NULL,
7841 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007842
7843 /*
7844 * Before adding a recursive via the BFD tracked ADJ-FIBs,
7845 * bring one of the sessions UP, leave the other down
7846 */
7847 bfd_10_10_10_1.local_state = BFD_STATE_up;
7848 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
7849 bfd_10_10_10_2.local_state = BFD_STATE_down;
7850 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7851
7852 /*
7853 * A recursive prefix via both of the ADJ FIBs
7854 */
7855 fib_prefix_t pfx_200_0_0_0_s_24 = {
7856 .fp_proto = FIB_PROTOCOL_IP4,
7857 .fp_len = 32,
7858 .fp_addr = {
7859 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
7860 },
7861 };
7862 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
7863
7864 dpo_10_10_10_1 =
7865 fib_entry_contribute_ip_forwarding(
7866 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
7867 dpo_10_10_10_2 =
7868 fib_entry_contribute_ip_forwarding(
7869 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
7870
7871 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
7872 .type = FT_LB_O_LB,
7873 .lb = {
7874 .lb = dpo_10_10_10_1->dpoi_index,
7875 },
7876 };
7877 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
7878 .type = FT_LB_O_LB,
7879 .lb = {
7880 .lb = dpo_10_10_10_2->dpoi_index,
7881 },
7882 };
7883
7884 /*
7885 * A prefix via the adj-fib that is BFD down => DROP
7886 */
7887 fei = fib_table_entry_path_add(0,
7888 &pfx_200_0_0_0_s_24,
7889 FIB_SOURCE_API,
7890 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007891 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007892 &nh_10_10_10_2,
7893 ~0, // recursive
7894 0, // default fib index
7895 1,
7896 NULL,
7897 FIB_ROUTE_PATH_FLAG_NONE);
7898 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
7899 "%U resolves via drop",
7900 format_fib_prefix, &pfx_200_0_0_0_s_24);
7901
7902 /*
7903 * add a path via the UP BFD adj-fib.
7904 * we expect that the DOWN BFD ADJ FIB is not used.
7905 */
7906 fei = fib_table_entry_path_add(0,
7907 &pfx_200_0_0_0_s_24,
7908 FIB_SOURCE_API,
7909 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07007910 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007911 &nh_10_10_10_1,
7912 ~0, // recursive
7913 0, // default fib index
7914 1,
7915 NULL,
7916 FIB_ROUTE_PATH_FLAG_NONE);
7917
7918 FIB_TEST(fib_test_validate_entry(fei,
7919 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7920 1,
7921 &lb_o_10_10_10_1),
7922 "Recursive %U only UP BFD adj-fibs",
7923 format_fib_prefix, &pfx_200_0_0_0_s_24);
7924
7925 /*
7926 * Send a BFD state change to UP - both sessions are now up
7927 * the recursive prefix should LB over both
7928 */
7929 bfd_10_10_10_2.local_state = BFD_STATE_up;
7930 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7931
7932
7933 FIB_TEST(fib_test_validate_entry(fei,
7934 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7935 2,
7936 &lb_o_10_10_10_1,
7937 &lb_o_10_10_10_2),
7938 "Recursive %U via both UP BFD adj-fibs",
7939 format_fib_prefix, &pfx_200_0_0_0_s_24);
7940
7941 /*
7942 * Send a BFD state change to DOWN
7943 * the recursive prefix should exclude the down
7944 */
7945 bfd_10_10_10_2.local_state = BFD_STATE_down;
7946 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
7947
7948
7949 FIB_TEST(fib_test_validate_entry(fei,
7950 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7951 1,
7952 &lb_o_10_10_10_1),
7953 "Recursive %U via only UP",
7954 format_fib_prefix, &pfx_200_0_0_0_s_24);
7955
7956 /*
7957 * Delete the BFD session while it is in the DOWN state.
7958 * FIB should consider the entry's state as back up
7959 */
7960 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
7961
7962 FIB_TEST(fib_test_validate_entry(fei,
7963 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7964 2,
7965 &lb_o_10_10_10_1,
7966 &lb_o_10_10_10_2),
7967 "Recursive %U via both UP BFD adj-fibs post down session delete",
7968 format_fib_prefix, &pfx_200_0_0_0_s_24);
7969
7970 /*
7971 * Delete the BFD other session while it is in the UP state.
7972 */
7973 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7974
7975 FIB_TEST(fib_test_validate_entry(fei,
7976 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7977 2,
7978 &lb_o_10_10_10_1,
7979 &lb_o_10_10_10_2),
7980 "Recursive %U via both UP BFD adj-fibs post up session delete",
7981 format_fib_prefix, &pfx_200_0_0_0_s_24);
7982
7983 /*
7984 * cleaup
7985 */
7986 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
7987 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
7988 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
7989
7990 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
7991 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
7992
7993 adj_unlock(ai_10_10_10_1);
7994 /*
7995 * test no-one left behind
7996 */
7997 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
7998 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
7999
8000 /*
8001 * Single-hop BFD tests
8002 */
8003 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8004 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8005
8006 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8007
8008 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8009 VNET_LINK_IP4,
8010 &nh_10_10_10_1,
8011 tm->hw[0]->sw_if_index);
8012 /*
8013 * whilst the BFD session is not signalled, the adj is up
8014 */
8015 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8016
8017 /*
8018 * bring the BFD session up
8019 */
8020 bfd_10_10_10_1.local_state = BFD_STATE_up;
8021 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8022 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8023
8024 /*
8025 * bring the BFD session down
8026 */
8027 bfd_10_10_10_1.local_state = BFD_STATE_down;
8028 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8029 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8030
8031
8032 /*
8033 * add an attached next hop FIB entry via the down adj
8034 */
8035 fib_prefix_t pfx_5_5_5_5_s_32 = {
8036 .fp_addr = {
8037 .ip4 = {
8038 .as_u32 = clib_host_to_net_u32(0x05050505),
8039 },
8040 },
8041 .fp_len = 32,
8042 .fp_proto = FIB_PROTOCOL_IP4,
8043 };
8044
8045 fei = fib_table_entry_path_add(0,
8046 &pfx_5_5_5_5_s_32,
8047 FIB_SOURCE_CLI,
8048 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008049 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008050 &nh_10_10_10_1,
8051 tm->hw[0]->sw_if_index,
8052 ~0, // invalid fib index
8053 1,
8054 NULL,
8055 FIB_ROUTE_PATH_FLAG_NONE);
8056 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8057 "%U resolves via drop",
8058 format_fib_prefix, &pfx_5_5_5_5_s_32);
8059
8060 /*
8061 * Add a path via an ADJ that is up
8062 */
8063 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8064 VNET_LINK_IP4,
8065 &nh_10_10_10_2,
8066 tm->hw[0]->sw_if_index);
8067
8068 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8069 .type = FT_LB_ADJ,
8070 .adj = {
8071 .adj = ai_10_10_10_2,
8072 },
8073 };
8074 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8075
8076 fei = fib_table_entry_path_add(0,
8077 &pfx_5_5_5_5_s_32,
8078 FIB_SOURCE_CLI,
8079 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008080 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008081 &nh_10_10_10_2,
8082 tm->hw[0]->sw_if_index,
8083 ~0, // invalid fib index
8084 1,
8085 NULL,
8086 FIB_ROUTE_PATH_FLAG_NONE);
8087
8088 FIB_TEST(fib_test_validate_entry(fei,
8089 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8090 1,
8091 &adj_o_10_10_10_2),
8092 "BFD sourced %U via %U",
8093 format_fib_prefix, &pfx_5_5_5_5_s_32,
8094 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8095
8096 /*
8097 * Bring up the down session - should now LB
8098 */
8099 bfd_10_10_10_1.local_state = BFD_STATE_up;
8100 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8101 FIB_TEST(fib_test_validate_entry(fei,
8102 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8103 2,
8104 &adj_o_10_10_10_1,
8105 &adj_o_10_10_10_2),
8106 "BFD sourced %U via noth adjs",
8107 format_fib_prefix, &pfx_5_5_5_5_s_32);
8108
8109 /*
8110 * remove the BFD session state from the adj
8111 */
8112 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8113
8114 /*
8115 * clean-up
8116 */
8117 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8118 adj_unlock(ai_10_10_10_1);
8119 adj_unlock(ai_10_10_10_2);
8120
8121 /*
8122 * test no-one left behind
8123 */
8124 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8125 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8126 return (0);
8127}
8128
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008129static int
8130lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008131{
8132 const mpls_label_t deag_label = 50;
8133 const u32 lfib_index = 0;
8134 const u32 fib_index = 0;
Neale Ranns948e00f2016-10-20 13:39:34 +01008135 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008136 const dpo_id_t *dpo1;
8137 fib_node_index_t lfe;
8138 lookup_dpo_t *lkd;
8139 test_main_t *tm;
8140 int lb_count;
Neale Rannsad422ed2016-11-02 14:20:04 +00008141 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008142
8143 tm = &test_main;
8144 lb_count = pool_elts(load_balance_pool);
8145
8146 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
8147 adj_nbr_db_size());
8148
8149 /*
8150 * MPLS enable an interface so we get the MPLS table created
8151 */
Neale Ranns2297af02017-09-12 09:45:04 -07008152 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008153 mpls_sw_interface_enable_disable(&mpls_main,
8154 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008155 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008156
Neale Rannsad422ed2016-11-02 14:20:04 +00008157 ip46_address_t nh_10_10_10_1 = {
8158 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
8159 };
8160 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8161 VNET_LINK_MPLS,
8162 &nh_10_10_10_1,
8163 tm->hw[0]->sw_if_index);
8164
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008165 /*
8166 * Test the specials stack properly.
8167 */
8168 fib_prefix_t exp_null_v6_pfx = {
8169 .fp_proto = FIB_PROTOCOL_MPLS,
8170 .fp_eos = MPLS_EOS,
8171 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8172 .fp_payload_proto = DPO_PROTO_IP6,
8173 };
8174 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8175 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
8176 "%U/%U present",
8177 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8178 format_mpls_eos_bit, MPLS_EOS);
8179 fib_entry_contribute_forwarding(lfe,
8180 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8181 &dpo);
8182 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8183 lkd = lookup_dpo_get(dpo1->dpoi_index);
8184
8185 FIB_TEST((fib_index == lkd->lkd_fib_index),
8186 "%U/%U is deag in %d %U",
8187 format_mpls_unicast_label, deag_label,
8188 format_mpls_eos_bit, MPLS_EOS,
8189 lkd->lkd_fib_index,
8190 format_dpo_id, &dpo, 0);
8191 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8192 "%U/%U is dst deag",
8193 format_mpls_unicast_label, deag_label,
8194 format_mpls_eos_bit, MPLS_EOS);
8195 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8196 "%U/%U is lookup in interface's table",
8197 format_mpls_unicast_label, deag_label,
8198 format_mpls_eos_bit, MPLS_EOS);
8199 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8200 "%U/%U is %U dst deag",
8201 format_mpls_unicast_label, deag_label,
8202 format_mpls_eos_bit, MPLS_EOS,
8203 format_dpo_proto, lkd->lkd_proto);
8204
8205
8206 /*
8207 * A route deag route for EOS
8208 */
8209 fib_prefix_t pfx = {
8210 .fp_proto = FIB_PROTOCOL_MPLS,
8211 .fp_eos = MPLS_EOS,
8212 .fp_label = deag_label,
8213 .fp_payload_proto = DPO_PROTO_IP4,
8214 };
8215 lfe = fib_table_entry_path_add(lfib_index,
8216 &pfx,
8217 FIB_SOURCE_CLI,
8218 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008219 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008220 &zero_addr,
8221 ~0,
8222 fib_index,
8223 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008224 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008225 FIB_ROUTE_PATH_FLAG_NONE);
8226
8227 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8228 "%U/%U present",
8229 format_mpls_unicast_label, deag_label,
8230 format_mpls_eos_bit, MPLS_EOS);
8231
8232 fib_entry_contribute_forwarding(lfe,
8233 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8234 &dpo);
8235 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8236 lkd = lookup_dpo_get(dpo1->dpoi_index);
8237
8238 FIB_TEST((fib_index == lkd->lkd_fib_index),
8239 "%U/%U is deag in %d %U",
8240 format_mpls_unicast_label, deag_label,
8241 format_mpls_eos_bit, MPLS_EOS,
8242 lkd->lkd_fib_index,
8243 format_dpo_id, &dpo, 0);
8244 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8245 "%U/%U is dst deag",
8246 format_mpls_unicast_label, deag_label,
8247 format_mpls_eos_bit, MPLS_EOS);
8248 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8249 "%U/%U is %U dst deag",
8250 format_mpls_unicast_label, deag_label,
8251 format_mpls_eos_bit, MPLS_EOS,
8252 format_dpo_proto, lkd->lkd_proto);
8253
8254 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8255
8256 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8257 &pfx)),
8258 "%U/%U not present",
8259 format_mpls_unicast_label, deag_label,
8260 format_mpls_eos_bit, MPLS_EOS);
8261
8262 /*
8263 * A route deag route for non-EOS
8264 */
8265 pfx.fp_eos = MPLS_NON_EOS;
8266 lfe = fib_table_entry_path_add(lfib_index,
8267 &pfx,
8268 FIB_SOURCE_CLI,
8269 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008270 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008271 &zero_addr,
8272 ~0,
8273 lfib_index,
8274 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00008275 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008276 FIB_ROUTE_PATH_FLAG_NONE);
8277
8278 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8279 "%U/%U present",
8280 format_mpls_unicast_label, deag_label,
8281 format_mpls_eos_bit, MPLS_NON_EOS);
8282
8283 fib_entry_contribute_forwarding(lfe,
8284 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8285 &dpo);
8286 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8287 lkd = lookup_dpo_get(dpo1->dpoi_index);
8288
8289 FIB_TEST((fib_index == lkd->lkd_fib_index),
8290 "%U/%U is deag in %d %U",
8291 format_mpls_unicast_label, deag_label,
8292 format_mpls_eos_bit, MPLS_NON_EOS,
8293 lkd->lkd_fib_index,
8294 format_dpo_id, &dpo, 0);
8295 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8296 "%U/%U is dst deag",
8297 format_mpls_unicast_label, deag_label,
8298 format_mpls_eos_bit, MPLS_NON_EOS);
8299
8300 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8301 "%U/%U is %U dst deag",
8302 format_mpls_unicast_label, deag_label,
8303 format_mpls_eos_bit, MPLS_NON_EOS,
8304 format_dpo_proto, lkd->lkd_proto);
8305
8306 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8307
8308 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8309 &pfx)),
8310 "%U/%U not present",
8311 format_mpls_unicast_label, deag_label,
8312 format_mpls_eos_bit, MPLS_EOS);
8313
Neale Rannsad422ed2016-11-02 14:20:04 +00008314 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008315
Neale Rannsad422ed2016-11-02 14:20:04 +00008316 /*
8317 * An MPLS x-connect
8318 */
8319 fib_prefix_t pfx_1200 = {
8320 .fp_len = 21,
8321 .fp_proto = FIB_PROTOCOL_MPLS,
8322 .fp_label = 1200,
8323 .fp_eos = MPLS_NON_EOS,
8324 };
8325 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
8326 .type = FT_LB_LABEL_STACK_O_ADJ,
8327 .label_stack_o_adj = {
8328 .adj = ai_mpls_10_10_10_1,
8329 .label_stack_size = 4,
8330 .label_stack = {
8331 200, 300, 400, 500,
8332 },
8333 .eos = MPLS_NON_EOS,
8334 },
8335 };
8336 dpo_id_t neos_1200 = DPO_INVALID;
8337 dpo_id_t ip_1200 = DPO_INVALID;
8338 mpls_label_t *l200 = NULL;
8339 vec_add1(l200, 200);
8340 vec_add1(l200, 300);
8341 vec_add1(l200, 400);
8342 vec_add1(l200, 500);
8343
8344 lfe = fib_table_entry_update_one_path(fib_index,
8345 &pfx_1200,
8346 FIB_SOURCE_API,
8347 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008348 DPO_PROTO_IP4,
Neale Rannsad422ed2016-11-02 14:20:04 +00008349 &nh_10_10_10_1,
8350 tm->hw[0]->sw_if_index,
8351 ~0, // invalid fib index
8352 1,
8353 l200,
8354 FIB_ROUTE_PATH_FLAG_NONE);
8355
8356 FIB_TEST(fib_test_validate_entry(lfe,
8357 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8358 1,
8359 &neos_o_10_10_10_1),
8360 "1200/0 LB 1 buckets via: "
8361 "adj 10.10.11.1");
8362
8363 /*
8364 * A recursive route via the MPLS x-connect
8365 */
8366 fib_prefix_t pfx_2_2_2_3_s_32 = {
8367 .fp_len = 32,
8368 .fp_proto = FIB_PROTOCOL_IP4,
8369 .fp_addr = {
8370 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8371 },
8372 };
8373 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008374 .frp_proto = DPO_PROTO_MPLS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008375 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008376 .frp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008377 .frp_sw_if_index = ~0, // recurive
8378 .frp_fib_index = 0, // Default MPLS fib
8379 .frp_weight = 1,
8380 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8381 .frp_label_stack = NULL,
8382 };
8383 vec_add1(rpaths, rpath);
8384
8385 fib_table_entry_path_add2(fib_index,
8386 &pfx_2_2_2_3_s_32,
8387 FIB_SOURCE_API,
8388 FIB_ENTRY_FLAG_NONE,
8389 rpaths);
8390
8391 /*
8392 * A labelled recursive route via the MPLS x-connect
8393 */
8394 fib_prefix_t pfx_2_2_2_4_s_32 = {
8395 .fp_len = 32,
8396 .fp_proto = FIB_PROTOCOL_IP4,
8397 .fp_addr = {
8398 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8399 },
8400 };
8401 mpls_label_t *l999 = NULL;
8402 vec_add1(l999, 999);
8403 rpaths[0].frp_label_stack = l999,
8404
8405 fib_table_entry_path_add2(fib_index,
8406 &pfx_2_2_2_4_s_32,
8407 FIB_SOURCE_API,
8408 FIB_ENTRY_FLAG_NONE,
8409 rpaths);
8410
8411 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8412 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8413 &ip_1200);
8414 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8415 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8416 &neos_1200);
8417
8418 fib_test_lb_bucket_t ip_o_1200 = {
8419 .type = FT_LB_O_LB,
8420 .lb = {
8421 .lb = ip_1200.dpoi_index,
8422 },
8423 };
8424 fib_test_lb_bucket_t mpls_o_1200 = {
8425 .type = FT_LB_LABEL_O_LB,
8426 .label_o_lb = {
8427 .lb = neos_1200.dpoi_index,
8428 .label = 999,
8429 .eos = MPLS_EOS,
8430 },
8431 };
8432
8433 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
8434 FIB_TEST(fib_test_validate_entry(lfe,
8435 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8436 1,
8437 &ip_o_1200),
8438 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
8439 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
8440 FIB_TEST(fib_test_validate_entry(lfe,
8441 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8442 1,
8443 &mpls_o_1200),
8444 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
8445
8446 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8447 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8448 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8449
8450 dpo_reset(&neos_1200);
8451 dpo_reset(&ip_1200);
8452
8453 /*
8454 * A recursive via a label that does not exist
8455 */
8456 fib_test_lb_bucket_t bucket_drop = {
8457 .type = FT_LB_SPECIAL,
8458 .special = {
Neale Rannsf12a83f2017-04-18 09:09:40 -07008459 .adj = DPO_PROTO_IP4,
8460 },
8461 };
8462 fib_test_lb_bucket_t mpls_bucket_drop = {
8463 .type = FT_LB_SPECIAL,
8464 .special = {
Neale Rannsad422ed2016-11-02 14:20:04 +00008465 .adj = DPO_PROTO_MPLS,
8466 },
8467 };
8468
8469 rpaths[0].frp_label_stack = NULL;
8470 lfe = fib_table_entry_path_add2(fib_index,
8471 &pfx_2_2_2_4_s_32,
8472 FIB_SOURCE_API,
8473 FIB_ENTRY_FLAG_NONE,
8474 rpaths);
8475
8476 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
8477 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8478 &ip_1200);
8479 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8480
8481 FIB_TEST(fib_test_validate_entry(lfe,
8482 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8483 1,
Neale Ranns57b58602017-07-15 07:37:25 -07008484 &bucket_drop),
8485 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008486 lfe = fib_table_lookup(fib_index, &pfx_1200);
8487 FIB_TEST(fib_test_validate_entry(lfe,
8488 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8489 1,
8490 &bucket_drop),
Neale Rannsf12a83f2017-04-18 09:09:40 -07008491 "1200/neos LB 1 buckets via: ip4-DROP");
8492 FIB_TEST(fib_test_validate_entry(lfe,
8493 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8494 1,
8495 &mpls_bucket_drop),
8496 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008497
8498 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8499
8500 dpo_reset(&ip_1200);
8501
8502 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008503 * An rx-interface route.
8504 * like the tail of an mcast LSP
8505 */
8506 dpo_id_t idpo = DPO_INVALID;
8507
Neale Ranns43161a82017-08-12 02:12:00 -07008508 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008509 tm->hw[0]->sw_if_index,
8510 &idpo);
8511
8512 fib_prefix_t pfx_2500 = {
8513 .fp_len = 21,
8514 .fp_proto = FIB_PROTOCOL_MPLS,
8515 .fp_label = 2500,
8516 .fp_eos = MPLS_EOS,
8517 .fp_payload_proto = DPO_PROTO_IP4,
8518 };
8519 fib_test_lb_bucket_t rx_intf_0 = {
8520 .type = FT_LB_INTF,
8521 .adj = {
8522 .adj = idpo.dpoi_index,
8523 },
8524 };
8525
8526 lfe = fib_table_entry_update_one_path(fib_index,
8527 &pfx_2500,
8528 FIB_SOURCE_API,
8529 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008530 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008531 NULL,
8532 tm->hw[0]->sw_if_index,
8533 ~0, // invalid fib index
8534 0,
8535 NULL,
8536 FIB_ROUTE_PATH_INTF_RX);
8537 FIB_TEST(fib_test_validate_entry(lfe,
8538 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8539 1,
8540 &rx_intf_0),
8541 "2500 rx-interface 0");
8542 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8543
8544 /*
8545 * An MPLS mulicast entry
8546 */
8547 fib_prefix_t pfx_3500 = {
8548 .fp_len = 21,
8549 .fp_proto = FIB_PROTOCOL_MPLS,
8550 .fp_label = 3500,
8551 .fp_eos = MPLS_EOS,
8552 .fp_payload_proto = DPO_PROTO_IP4,
8553 };
8554 fib_test_rep_bucket_t mc_0 = {
8555 .type = FT_REP_LABEL_O_ADJ,
8556 .label_o_adj = {
8557 .adj = ai_mpls_10_10_10_1,
8558 .label = 3300,
8559 .eos = MPLS_EOS,
8560 },
8561 };
8562 fib_test_rep_bucket_t mc_intf_0 = {
8563 .type = FT_REP_INTF,
8564 .adj = {
8565 .adj = idpo.dpoi_index,
8566 },
8567 };
8568 mpls_label_t *l3300 = NULL;
8569 vec_add1(l3300, 3300);
8570
8571 lfe = fib_table_entry_update_one_path(lfib_index,
8572 &pfx_3500,
8573 FIB_SOURCE_API,
8574 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008575 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008576 &nh_10_10_10_1,
8577 tm->hw[0]->sw_if_index,
8578 ~0, // invalid fib index
8579 1,
8580 l3300,
8581 FIB_ROUTE_PATH_FLAG_NONE);
8582 FIB_TEST(fib_test_validate_entry(lfe,
8583 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8584 1,
8585 &mc_0),
8586 "3500 via replicate over 10.10.10.1");
8587
8588 /*
8589 * MPLS Bud-node. Add a replication via an interface-receieve path
8590 */
8591 lfe = fib_table_entry_path_add(lfib_index,
8592 &pfx_3500,
8593 FIB_SOURCE_API,
8594 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008595 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008596 NULL,
8597 tm->hw[0]->sw_if_index,
8598 ~0, // invalid fib index
8599 0,
8600 NULL,
8601 FIB_ROUTE_PATH_INTF_RX);
8602 FIB_TEST(fib_test_validate_entry(lfe,
8603 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8604 2,
8605 &mc_0,
8606 &mc_intf_0),
8607 "3500 via replicate over 10.10.10.1 and interface-rx");
8608
8609 /*
8610 * Add a replication via an interface-free for-us path
8611 */
8612 fib_test_rep_bucket_t mc_disp = {
8613 .type = FT_REP_DISP_MFIB_LOOKUP,
8614 .adj = {
8615 .adj = idpo.dpoi_index,
8616 },
8617 };
8618 lfe = fib_table_entry_path_add(lfib_index,
8619 &pfx_3500,
8620 FIB_SOURCE_API,
8621 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07008622 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008623 NULL,
8624 5, // rpf-id
8625 0, // default table
8626 0,
8627 NULL,
8628 FIB_ROUTE_PATH_RPF_ID);
8629 FIB_TEST(fib_test_validate_entry(lfe,
8630 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8631 3,
8632 &mc_0,
8633 &mc_disp,
8634 &mc_intf_0),
8635 "3500 via replicate over 10.10.10.1 and interface-rx");
8636
8637
8638
8639 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8640 dpo_reset(&idpo);
8641
8642 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008643 * cleanup
8644 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008645 mpls_sw_interface_enable_disable(&mpls_main,
8646 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008647 0, 1);
8648 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008649
Neale Rannsad422ed2016-11-02 14:20:04 +00008650 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008651 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008652 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008653 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
8654 "interface_rx_dpo resources freed %d of %d",
8655 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008656
8657 return (0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008658}
8659
8660static clib_error_t *
8661fib_test (vlib_main_t * vm,
8662 unformat_input_t * input,
8663 vlib_cli_command_t * cmd_arg)
8664{
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008665 int res;
8666
8667 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008668 fib_test_mk_intf(4);
8669
Neale Ranns88fc83e2017-04-05 08:11:14 -07008670 if (unformat (input, "debug"))
8671 {
8672 fib_test_do_debug = 1;
8673 }
8674
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008675 if (unformat (input, "ip"))
8676 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008677 res += fib_test_v4();
8678 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008679 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008680 else if (unformat (input, "label"))
8681 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008682 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008683 }
8684 else if (unformat (input, "ae"))
8685 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008686 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008687 }
Neale Ranns57b58602017-07-15 07:37:25 -07008688 else if (unformat (input, "pref"))
8689 {
8690 res += fib_test_pref();
8691 }
Neale Rannsad422ed2016-11-02 14:20:04 +00008692 else if (unformat (input, "lfib"))
8693 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008694 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +00008695 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008696 else if (unformat (input, "walk"))
8697 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008698 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008699 }
Neale Ranns88fc83e2017-04-05 08:11:14 -07008700 else if (unformat (input, "bfd"))
8701 {
8702 res += fib_test_bfd();
8703 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008704 else
8705 {
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008706 res += fib_test_v4();
8707 res += fib_test_v6();
8708 res += fib_test_ae();
Neale Ranns88fc83e2017-04-05 08:11:14 -07008709 res += fib_test_bfd();
Neale Ranns57b58602017-07-15 07:37:25 -07008710 res += fib_test_pref();
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008711 res += fib_test_label();
8712 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -07008713
8714 /*
8715 * fib-walk process must be disabled in order for the walk tests to work
8716 */
8717 fib_walk_process_disable();
8718 res += fib_test_walk();
8719 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008720 }
8721
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008722 if (res)
8723 {
8724 return clib_error_return(0, "FIB Unit Test Failed");
8725 }
8726 else
8727 {
8728 return (NULL);
8729 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008730}
8731
8732VLIB_CLI_COMMAND (test_fib_command, static) = {
8733 .path = "test fib",
8734 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
8735 .function = fib_test,
8736};
8737
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008738clib_error_t *
8739fib_test_init (vlib_main_t *vm)
8740{
8741 return 0;
8742}
8743
8744VLIB_INIT_FUNCTION (fib_test_init);