blob: 492369c354096e5b0c97cc7236a670a864bfe9eb [file] [log] [blame]
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
Neale Rannsd792d9c2017-10-21 10:53:20 -070016#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010017#include <vnet/fib/ip6_fib.h>
18#include <vnet/fib/ip4_fib.h>
19#include <vnet/fib/mpls_fib.h>
20#include <vnet/adj/adj.h>
21#include <vnet/dpo/load_balance.h>
22#include <vnet/dpo/load_balance_map.h>
23#include <vnet/dpo/mpls_label_dpo.h>
24#include <vnet/dpo/lookup_dpo.h>
25#include <vnet/dpo/drop_dpo.h>
26#include <vnet/dpo/receive_dpo.h>
Neale Ranns948e00f2016-10-20 13:39:34 +010027#include <vnet/dpo/ip_null_dpo.h>
Neale Ranns88fc83e2017-04-05 08:11:14 -070028#include <vnet/bfd/bfd_main.h>
Neale Ranns43161a82017-08-12 02:12:00 -070029#include <vnet/dpo/interface_rx_dpo.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080030#include <vnet/dpo/replicate_dpo.h>
Neale Rannsf068c3e2018-01-03 04:18:48 -080031#include <vnet/dpo/dvr_dpo.h>
Neale Ranns62fe07c2017-10-31 12:28:22 -070032#include <vnet/dpo/mpls_disposition.h>
Neale Ranns2303cb12018-02-21 04:57:17 -080033#include <vnet/dpo/punt_dpo.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010034
35#include <vnet/mpls/mpls.h>
36
Neale Ranns6f631152017-10-03 08:20:21 -070037#include <vnet/fib/fib_test.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010038#include <vnet/fib/fib_path_list.h>
Neale Rannsad422ed2016-11-02 14:20:04 +000039#include <vnet/fib/fib_entry_src.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010040#include <vnet/fib/fib_walk.h>
41#include <vnet/fib/fib_node_list.h>
Neale Ranns3ee44042016-10-03 13:05:48 +010042#include <vnet/fib/fib_urpf_list.h>
Neale Ranns0bfe5d82016-08-25 15:29:12 +010043
Jakub Grajciar7b867a82017-12-08 16:28:42 +010044#include <vlib/unix/plugin.h>
45
Neale Ranns88fc83e2017-04-05 08:11:14 -070046/*
47 * Add debugs for passing tests
48 */
49static int fib_test_do_debug;
50
Neale Ranns0bfe5d82016-08-25 15:29:12 +010051#define FIB_TEST_I(_cond, _comment, _args...) \
52({ \
53 int _evald = (_cond); \
54 if (!(_evald)) { \
Neale Ranns2303cb12018-02-21 04:57:17 -080055 fformat(stderr, "FAIL:%d: " _comment "\n", \
56 __LINE__, ##_args); \
57 res = 1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010058 } else { \
Neale Ranns2303cb12018-02-21 04:57:17 -080059 if (fib_test_do_debug) \
Neale Ranns88fc83e2017-04-05 08:11:14 -070060 fformat(stderr, "PASS:%d: " _comment "\n", \
61 __LINE__, ##_args); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010062 } \
Neale Ranns2303cb12018-02-21 04:57:17 -080063 res; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010064})
65#define FIB_TEST(_cond, _comment, _args...) \
66{ \
Neale Ranns2303cb12018-02-21 04:57:17 -080067 if (FIB_TEST_I(_cond, _comment, ##_args)) { \
68 return 1; \
69 ASSERT(!("FAIL: " _comment)); \
Neale Ranns0bfe5d82016-08-25 15:29:12 +010070 } \
71}
72
73/**
74 * A 'i'm not fussed is this is not efficient' store of test data
75 */
76typedef struct test_main_t_ {
77 /**
78 * HW if indicies
79 */
80 u32 hw_if_indicies[4];
81 /**
82 * HW interfaces
83 */
84 vnet_hw_interface_t * hw[4];
85
86} test_main_t;
87static test_main_t test_main;
88
89/* fake ethernet device class, distinct from "fake-ethX" */
90static u8 * format_test_interface_name (u8 * s, va_list * args)
91{
92 u32 dev_instance = va_arg (*args, u32);
93 return format (s, "test-eth%d", dev_instance);
94}
95
96static uword dummy_interface_tx (vlib_main_t * vm,
Neale Ranns2303cb12018-02-21 04:57:17 -080097 vlib_node_runtime_t * node,
98 vlib_frame_t * frame)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010099{
Neale Ranns2303cb12018-02-21 04:57:17 -0800100 clib_warning ("you shouldn't be here, leaking buffers...");
101 return frame->n_vectors;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100102}
103
Neale Ranns8b37b872016-11-21 12:25:22 +0000104static clib_error_t *
105test_interface_admin_up_down (vnet_main_t * vnm,
106 u32 hw_if_index,
107 u32 flags)
108{
Neale Ranns2303cb12018-02-21 04:57:17 -0800109 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
110 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
111 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
112 return 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000113}
114
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100115VNET_DEVICE_CLASS (test_interface_device_class,static) = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800116 .name = "Test interface",
117 .format_device_name = format_test_interface_name,
118 .tx_function = dummy_interface_tx,
119 .admin_up_down_function = test_interface_admin_up_down,
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100120};
121
122static u8 *hw_address;
123
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000124static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100125fib_test_mk_intf (u32 ninterfaces)
126{
127 clib_error_t * error = NULL;
128 test_main_t *tm = &test_main;
Neale Ranns2303cb12018-02-21 04:57:17 -0800129 u32 i, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100130 u8 byte;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100131
Neale Ranns2303cb12018-02-21 04:57:17 -0800132 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100133 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
134
135 for (i=0; i<6; i++)
136 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800137 byte = 0xd0+i;
138 vec_add1(hw_address, byte);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100139 }
140
141 for (i = 0; i < ninterfaces; i++)
142 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800143 hw_address[5] = i;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100144
Neale Ranns2303cb12018-02-21 04:57:17 -0800145 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns8b37b872016-11-21 12:25:22 +0000146 test_interface_device_class.index,
Neale Ranns2303cb12018-02-21 04:57:17 -0800147 i /* instance */,
148 hw_address,
149 &tm->hw_if_indicies[i],
150 /* flag change */ 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100151
Neale Ranns2303cb12018-02-21 04:57:17 -0800152 FIB_TEST((NULL == error), "ADD interface %d", i);
153
Neale Ranns8b37b872016-11-21 12:25:22 +0000154 error = vnet_hw_interface_set_flags(vnet_get_main(),
155 tm->hw_if_indicies[i],
156 VNET_HW_INTERFACE_FLAG_LINK_UP);
157 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -0800158 tm->hw_if_indicies[i]);
159 vec_validate (ip4_main.fib_index_by_sw_if_index,
Neale Ranns8b37b872016-11-21 12:25:22 +0000160 tm->hw[i]->sw_if_index);
Neale Ranns2303cb12018-02-21 04:57:17 -0800161 vec_validate (ip6_main.fib_index_by_sw_if_index,
Neale Ranns8b37b872016-11-21 12:25:22 +0000162 tm->hw[i]->sw_if_index);
Neale Ranns2303cb12018-02-21 04:57:17 -0800163 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
164 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
Neale Ranns8b37b872016-11-21 12:25:22 +0000165
Neale Ranns2303cb12018-02-21 04:57:17 -0800166 error = vnet_sw_interface_set_flags(vnet_get_main(),
167 tm->hw[i]->sw_if_index,
168 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
169 FIB_TEST((NULL == error), "UP interface %d", i);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100170 }
171 /*
172 * re-eval after the inevitable realloc
173 */
174 for (i = 0; i < ninterfaces; i++)
175 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800176 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
177 tm->hw_if_indicies[i]);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100178 }
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000179
Neale Ranns2303cb12018-02-21 04:57:17 -0800180 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100181}
182
Neale Ranns3ee44042016-10-03 13:05:48 +0100183#define FIB_TEST_REC_FORW(_rec_prefix, _via_prefix, _bucket) \
Neale Ranns2303cb12018-02-21 04:57:17 -0800184 { \
185 const dpo_id_t *_rec_dpo = fib_entry_contribute_ip_forwarding( \
186 fib_table_lookup_exact_match(fib_index, (_rec_prefix))); \
187 const dpo_id_t *_via_dpo = fib_entry_contribute_ip_forwarding( \
188 fib_table_lookup(fib_index, (_via_prefix))); \
189 FIB_TEST(!dpo_cmp(_via_dpo, \
190 load_balance_get_bucket(_rec_dpo->dpoi_index, \
191 _bucket)), \
192 "%U is recursive via %U", \
193 format_fib_prefix, (_rec_prefix), \
194 format_fib_prefix, _via_prefix); \
195 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100196
197#define FIB_TEST_LB_BUCKET_VIA_ADJ(_prefix, _bucket, _ai) \
Neale Ranns2303cb12018-02-21 04:57:17 -0800198 { \
199 const dpo_id_t *_dpo = fib_entry_contribute_ip_forwarding( \
200 fib_table_lookup_exact_match(fib_index, (_prefix))); \
201 const dpo_id_t *_dpo1 = \
202 load_balance_get_bucket(_dpo->dpoi_index, _bucket); \
203 FIB_TEST(DPO_ADJACENCY == _dpo1->dpoi_type, "type is %U", \
204 format_dpo_type, _dpo1->dpoi_type); \
205 FIB_TEST((_ai == _dpo1->dpoi_index), \
206 "%U bucket %d resolves via %U", \
207 format_fib_prefix, (_prefix), \
208 _bucket, \
209 format_dpo_id, _dpo1, 0); \
210 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100211
Neale Ranns2303cb12018-02-21 04:57:17 -0800212#define FIB_TEST_RPF(_cond, _comment, _args...) \
213 { \
214 if (FIB_TEST_I(_cond, _comment, ##_args)) { \
215 return (1); \
216 } \
217 }
Neale Ranns3ee44042016-10-03 13:05:48 +0100218
219static int
220fib_test_urpf_is_equal (fib_node_index_t fei,
Neale Ranns2303cb12018-02-21 04:57:17 -0800221 fib_forward_chain_type_t fct,
222 u32 num, ...)
Neale Ranns3ee44042016-10-03 13:05:48 +0100223{
Neale Ranns948e00f2016-10-20 13:39:34 +0100224 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100225 fib_urpf_list_t *urpf;
Neale Ranns2303cb12018-02-21 04:57:17 -0800226 int ii, res;
Neale Ranns3ee44042016-10-03 13:05:48 +0100227 index_t ui;
228 va_list ap;
Neale Ranns3ee44042016-10-03 13:05:48 +0100229
230 va_start(ap, num);
231
Neale Ranns2303cb12018-02-21 04:57:17 -0800232 res = 0;
Neale Ranns3ee44042016-10-03 13:05:48 +0100233 fib_entry_contribute_forwarding(fei, fct, &dpo);
234 ui = load_balance_get_urpf(dpo.dpoi_index);
235
236 urpf = fib_urpf_list_get(ui);
237
238 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
Neale Ranns2303cb12018-02-21 04:57:17 -0800239 "RPF:%U len %d == %d",
240 format_fib_urpf_list, ui,
241 num, vec_len(urpf->furpf_itfs));
Neale Ranns3ee44042016-10-03 13:05:48 +0100242 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
Neale Ranns2303cb12018-02-21 04:57:17 -0800243 "RPF:%U check-size %d == %d",
244 format_fib_urpf_list, ui,
245 num, vec_len(urpf->furpf_itfs));
Neale Ranns3ee44042016-10-03 13:05:48 +0100246
247 for (ii = 0; ii < num; ii++)
248 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800249 adj_index_t ai = va_arg(ap, adj_index_t);
Neale Ranns3ee44042016-10-03 13:05:48 +0100250
Neale Ranns2303cb12018-02-21 04:57:17 -0800251 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
252 "RPF:%d item:%d - %d == %d",
253 ui, ii, ai, urpf->furpf_itfs[ii]);
254 FIB_TEST_RPF(fib_urpf_check(ui, ai),
255 "RPF:%d %d found",
256 ui, ai);
Neale Ranns3ee44042016-10-03 13:05:48 +0100257 }
258
259 dpo_reset(&dpo);
260
Neale Ranns5899fde2016-10-12 13:51:05 +0100261 va_end(ap);
262
Neale Ranns2303cb12018-02-21 04:57:17 -0800263 return (res);
Neale Ranns3ee44042016-10-03 13:05:48 +0100264}
265
Neale Rannsb80c5362016-10-08 13:03:40 +0100266static u8*
267fib_test_build_rewrite (u8 *eth_addr)
268{
269 u8* rewrite = NULL;
270
271 vec_validate(rewrite, 13);
272
273 memcpy(rewrite, eth_addr, 6);
274 memcpy(rewrite+6, eth_addr, 6);
275
276 return (rewrite);
277}
278
Neale Ranns2303cb12018-02-21 04:57:17 -0800279#define FIB_TEST_LB(_cond, _comment, _args...) \
280 { \
281 if (FIB_TEST_I(_cond, _comment, ##_args)) { \
282 return (1); \
283 } \
284 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000285
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800286int
287fib_test_validate_rep_v (const replicate_t *rep,
288 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200289 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800290{
291 const fib_test_rep_bucket_t *exp;
292 const dpo_id_t *dpo;
Neale Ranns2303cb12018-02-21 04:57:17 -0800293 int bucket, res;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800294
Neale Ranns2303cb12018-02-21 04:57:17 -0800295 res = 0;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800296 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
297 "n_buckets = %d", rep->rep_n_buckets);
298
299 for (bucket = 0; bucket < n_buckets; bucket++)
300 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800301 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800302
303 dpo = replicate_get_bucket_i(rep, bucket);
304
Neale Ranns2303cb12018-02-21 04:57:17 -0800305 switch (exp->type)
306 {
307 case FT_REP_LABEL_O_ADJ:
308 {
309 const mpls_label_dpo_t *mld;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800310 mpls_label_t hdr;
Neale Ranns2303cb12018-02-21 04:57:17 -0800311
Neale Ranns31ed7442018-02-23 05:29:09 -0800312 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
313 == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800314 "bucket %d stacks on %U",
315 bucket,
316 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800317
318 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800319 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
320
Neale Ranns2303cb12018-02-21 04:57:17 -0800321 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
322 exp->label_o_adj.label),
323 "bucket %d stacks on label %d",
324 bucket,
325 exp->label_o_adj.label);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800326
Neale Ranns2303cb12018-02-21 04:57:17 -0800327 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
328 exp->label_o_adj.eos),
329 "bucket %d stacks on label %d %U",
330 bucket,
331 exp->label_o_adj.label,
332 format_mpls_eos_bit, exp->label_o_adj.eos);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800333
Neale Ranns2303cb12018-02-21 04:57:17 -0800334 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
335 "bucket %d label stacks on %U",
336 bucket,
337 format_dpo_type, mld->mld_dpo.dpoi_type);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800338
Neale Ranns2303cb12018-02-21 04:57:17 -0800339 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
340 "bucket %d label stacks on adj %d",
341 bucket,
342 exp->label_o_adj.adj);
343 }
344 break;
345 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700346 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800347 "bucket %d stacks on %U",
348 bucket,
349 format_dpo_type, dpo->dpoi_type);
350
351 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
352 "bucket %d stacks on adj %d",
353 bucket,
354 exp->adj.adj);
Neale Ranns2303cb12018-02-21 04:57:17 -0800355 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800356 case FT_REP_DISP_MFIB_LOOKUP:
357// ASSERT(0);
358 break;
359 }
360 }
361
Neale Ranns2303cb12018-02-21 04:57:17 -0800362 return (res);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800363}
364
365int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000366fib_test_validate_lb_v (const load_balance_t *lb,
Neale Ranns2303cb12018-02-21 04:57:17 -0800367 int n_buckets,
368 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000369{
370 const dpo_id_t *dpo;
Neale Ranns2303cb12018-02-21 04:57:17 -0800371 int bucket, res;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000372
Neale Ranns2303cb12018-02-21 04:57:17 -0800373 res = 0;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000374 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
375
376 for (bucket = 0; bucket < n_buckets; bucket++)
377 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800378 const fib_test_lb_bucket_t *exp;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000379
Neale Ranns2303cb12018-02-21 04:57:17 -0800380 exp = va_arg(*ap, fib_test_lb_bucket_t*);
381 dpo = load_balance_get_bucket_i(lb, bucket);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000382
383 switch (exp->type)
384 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000385 case FT_LB_LABEL_STACK_O_ADJ:
386 {
387 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800388 mpls_label_dpo_flags_t mf;
Neale Rannsad422ed2016-11-02 14:20:04 +0000389 mpls_label_t hdr;
390 u32 ii;
391
Neale Ranns31ed7442018-02-23 05:29:09 -0800392 mf = ((exp->label_stack_o_adj.mode ==
393 FIB_MPLS_LSP_MODE_UNIFORM) ?
394 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
395 MPLS_LABEL_DPO_FLAG_NONE);
396 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Rannsad422ed2016-11-02 14:20:04 +0000397 "bucket %d stacks on %U",
398 bucket,
399 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800400
Neale Rannsad422ed2016-11-02 14:20:04 +0000401 mld = mpls_label_dpo_get(dpo->dpoi_index);
402
403 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
404 "label stack size",
405 mld->mld_n_labels);
406
407 for (ii = 0; ii < mld->mld_n_labels; ii++)
408 {
409 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
410 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
411 exp->label_stack_o_adj.label_stack[ii]),
412 "bucket %d stacks on label %d",
413 bucket,
414 exp->label_stack_o_adj.label_stack[ii]);
415
416 if (ii == mld->mld_n_labels-1)
417 {
418 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
419 exp->label_o_adj.eos),
420 "bucket %d stacks on label %d %U!=%U",
421 bucket,
422 exp->label_stack_o_adj.label_stack[ii],
423 format_mpls_eos_bit, exp->label_o_adj.eos,
424 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
425 }
426 else
427 {
428 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
429 "bucket %d stacks on label %d %U",
430 bucket,
431 exp->label_stack_o_adj.label_stack[ii],
432 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
433 }
434 }
435
436 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
437 "bucket %d label stacks on %U",
438 bucket,
439 format_dpo_type, mld->mld_dpo.dpoi_type);
440
441 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
442 "bucket %d label stacks on adj %d",
443 bucket,
444 exp->label_stack_o_adj.adj);
445 }
446 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000447 case FT_LB_LABEL_O_ADJ:
448 {
449 const mpls_label_dpo_t *mld;
450 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800451 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
452 == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000453 "bucket %d stacks on %U",
454 bucket,
455 format_dpo_type, dpo->dpoi_type);
456
457 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000458 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000459
460 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
461 exp->label_o_adj.label),
462 "bucket %d stacks on label %d",
463 bucket,
464 exp->label_o_adj.label);
465
466 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
467 exp->label_o_adj.eos),
468 "bucket %d stacks on label %d %U",
469 bucket,
470 exp->label_o_adj.label,
471 format_mpls_eos_bit, exp->label_o_adj.eos);
472
473 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
474 "bucket %d label stacks on %U",
475 bucket,
476 format_dpo_type, mld->mld_dpo.dpoi_type);
477
478 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
479 "bucket %d label stacks on adj %d",
480 bucket,
481 exp->label_o_adj.adj);
482 }
483 break;
484 case FT_LB_LABEL_O_LB:
485 {
486 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800487 mpls_label_dpo_flags_t mf;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000488 mpls_label_t hdr;
489
Neale Ranns31ed7442018-02-23 05:29:09 -0800490 mf = ((exp->label_o_lb.mode ==
491 FIB_MPLS_LSP_MODE_UNIFORM) ?
492 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
493 MPLS_LABEL_DPO_FLAG_NONE);
494 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000495 "bucket %d stacks on %U",
496 bucket,
497 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800498
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000499 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000500 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000501
Neale Rannsad422ed2016-11-02 14:20:04 +0000502 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
503 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000504 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
505 exp->label_o_lb.label),
506 "bucket %d stacks on label %d",
507 bucket,
508 exp->label_o_lb.label);
509
510 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
511 exp->label_o_lb.eos),
512 "bucket %d stacks on label %d %U",
513 bucket,
514 exp->label_o_lb.label,
515 format_mpls_eos_bit, exp->label_o_lb.eos);
516
517 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
518 "bucket %d label stacks on %U",
519 bucket,
520 format_dpo_type, mld->mld_dpo.dpoi_type);
521
522 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
523 "bucket %d label stacks on LB %d",
524 bucket,
525 exp->label_o_lb.lb);
526 }
527 break;
528 case FT_LB_ADJ:
Neale Ranns756cd942018-04-06 09:18:11 -0700529 res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
530 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
531 "bucket %d stacks on %U",
532 bucket,
533 format_dpo_type, dpo->dpoi_type);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000534 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
535 "bucket %d stacks on adj %d",
536 bucket,
537 exp->adj.adj);
538 break;
Neale Ranns31ed7442018-02-23 05:29:09 -0800539 case FT_LB_MPLS_DISP_PIPE_O_ADJ:
Neale Ranns62fe07c2017-10-31 12:28:22 -0700540 {
541 const mpls_disp_dpo_t *mdd;
542
Neale Ranns756cd942018-04-06 09:18:11 -0700543 res = FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type),
Neale Ranns62fe07c2017-10-31 12:28:22 -0700544 "bucket %d stacks on %U",
545 bucket,
546 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800547
Neale Ranns62fe07c2017-10-31 12:28:22 -0700548 mdd = mpls_disp_dpo_get(dpo->dpoi_index);
549
550 dpo = &mdd->mdd_dpo;
551
Neale Ranns756cd942018-04-06 09:18:11 -0700552 res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
553 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
554 "bucket %d stacks on %U",
555 bucket,
556 format_dpo_type, dpo->dpoi_type);
Neale Ranns62fe07c2017-10-31 12:28:22 -0700557 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
558 "bucket %d stacks on adj %d",
559 bucket,
560 exp->adj.adj);
561 break;
562 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800563 case FT_LB_INTF:
Neale Ranns756cd942018-04-06 09:18:11 -0700564 res = FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
565 "bucket %d stacks on %U",
566 bucket,
567 format_dpo_type, dpo->dpoi_type);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800568 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
569 "bucket %d stacks on adj %d",
570 bucket,
571 exp->adj.adj);
572 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700573 case FT_LB_L2:
Neale Ranns756cd942018-04-06 09:18:11 -0700574 res = FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
575 "bucket %d stacks on %U",
576 bucket,
577 format_dpo_type, dpo->dpoi_type);
Neale Ranns6f631152017-10-03 08:20:21 -0700578 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
579 "bucket %d stacks on adj %d",
580 bucket,
581 exp->adj.adj);
582 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000583 case FT_LB_O_LB:
Neale Ranns756cd942018-04-06 09:18:11 -0700584 res = FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
585 "bucket %d stacks on %U",
586 bucket,
587 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800588 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
589 "bucket %d stacks on lb %d not %d",
590 bucket,
591 dpo->dpoi_index,
Neale Ranns57b58602017-07-15 07:37:25 -0700592 exp->lb.lb);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700593 break;
Neale Ranns2303cb12018-02-21 04:57:17 -0800594 case FT_LB_BIER_TABLE:
595 FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type),
Neale Rannsd792d9c2017-10-21 10:53:20 -0700596 "bucket %d stacks on %U",
597 bucket,
598 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800599 FIB_TEST_LB((exp->bier.table == dpo->dpoi_index),
600 "bucket %d stacks on lb %d",
601 bucket,
602 exp->bier.table);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700603 break;
Neale Ranns2303cb12018-02-21 04:57:17 -0800604 case FT_LB_BIER_FMASK:
605 FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type),
Neale Rannsd792d9c2017-10-21 10:53:20 -0700606 "bucket %d stacks on %U",
607 bucket,
608 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800609 FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index),
610 "bucket %d stacks on lb %d",
611 bucket,
612 exp->bier.fmask);
613 break;
614 case FT_LB_DROP:
615 FIB_TEST_LB((DPO_DROP == dpo->dpoi_type),
616 "bucket %d stacks on %U",
617 bucket,
618 format_dpo_type, dpo->dpoi_type);
619 break;
620 case FT_LB_PUNT:
621 FIB_TEST_LB((DPO_PUNT == dpo->dpoi_type),
622 "bucket %d stacks on %U",
623 bucket,
624 format_dpo_type, dpo->dpoi_type);
625 break;
626 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000627 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800628 return (res);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000629}
630
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800631int
Neale Rannsd792d9c2017-10-21 10:53:20 -0700632fib_test_validate_lb (const dpo_id_t *dpo,
Neale Ranns2303cb12018-02-21 04:57:17 -0800633 int n_buckets,
634 ...)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700635{
636 const load_balance_t *lb;
637 va_list ap;
638 int res;
639
Neale Ranns2303cb12018-02-21 04:57:17 -0800640 res = 0;
Neale Rannsd792d9c2017-10-21 10:53:20 -0700641 va_start(ap, n_buckets);
642
Neale Rannsac64b712018-10-08 14:51:11 +0000643 if (!FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
644 "Entry links to %U",
645 format_dpo_type, dpo->dpoi_type))
Neale Ranns93149bb2017-11-15 10:44:07 -0800646 {
647 lb = load_balance_get(dpo->dpoi_index);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700648
Neale Ranns93149bb2017-11-15 10:44:07 -0800649 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
650 }
651 else
652 {
Neale Rannsac64b712018-10-08 14:51:11 +0000653 res = 1;
Neale Ranns93149bb2017-11-15 10:44:07 -0800654 }
Neale Rannsd792d9c2017-10-21 10:53:20 -0700655
656 va_end(ap);
657
658 return (res);
659}
660
661int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000662fib_test_validate_entry (fib_node_index_t fei,
Neale Ranns2303cb12018-02-21 04:57:17 -0800663 fib_forward_chain_type_t fct,
664 int n_buckets,
665 ...)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000666{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000667 dpo_id_t dpo = DPO_INVALID;
Neale Rannsc5d43172018-07-30 08:04:40 -0700668 const fib_prefix_t *pfx;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000669 index_t fw_lbi;
670 u32 fib_index;
671 va_list ap;
672 int res;
673
674 va_start(ap, n_buckets);
675
Neale Ranns2303cb12018-02-21 04:57:17 -0800676 res = 0;
Neale Rannsc5d43172018-07-30 08:04:40 -0700677 pfx = fib_entry_get_prefix(fei);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000678 fib_index = fib_entry_get_fib_index(fei);
679 fib_entry_contribute_forwarding(fei, fct, &dpo);
680
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800681 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000682 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800683 const replicate_t *rep;
684
685 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200686 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800687 }
688 else
689 {
690 const load_balance_t *lb;
691
692 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
Neale Ranns89541992017-04-06 04:41:02 -0700693 "%U Entry links to %U",
Neale Rannsc5d43172018-07-30 08:04:40 -0700694 format_fib_prefix, pfx,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800695 format_dpo_type, dpo.dpoi_type);
696
697 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200698 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800699
700 /*
701 * ensure that the LB contributed by the entry is the
702 * same as the LB in the forwarding tables
703 */
704 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000705 {
Neale Rannsc5d43172018-07-30 08:04:40 -0700706 switch (pfx->fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000707 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800708 case FIB_PROTOCOL_IP4:
Neale Rannsc5d43172018-07-30 08:04:40 -0700709 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx->fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000710 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800711 case FIB_PROTOCOL_IP6:
Neale Rannsc5d43172018-07-30 08:04:40 -0700712 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx->fp_addr.ip6);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800713 break;
714 case FIB_PROTOCOL_MPLS:
715 {
716 mpls_unicast_header_t hdr = {
717 .label_exp_s_ttl = 0,
718 };
719
Neale Rannsc5d43172018-07-30 08:04:40 -0700720 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx->fp_label);
721 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx->fp_eos);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800722 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
723
724 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
725 break;
726 }
727 default:
728 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000729 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800730 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
Neale Ranns89541992017-04-06 04:41:02 -0700731 "Contributed LB = FW LB:\n fwd:%U\n cont:%U",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800732 format_load_balance, fw_lbi, 0,
733 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000734 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000735 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000736
737 dpo_reset(&dpo);
738
739 va_end(ap);
740
741 return (res);
742}
743
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000744static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100745fib_test_v4 (void)
746{
747 /*
748 * In the default table check for the presence and correct forwarding
749 * of the special entries
750 */
751 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
752 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
753 const ip_adjacency_t *adj;
754 const load_balance_t *lb;
755 test_main_t *tm;
756 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700757 int lb_count;
Neale Ranns2303cb12018-02-21 04:57:17 -0800758 int ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100759
Neale Ranns2303cb12018-02-21 04:57:17 -0800760 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100761 /* via 10.10.10.1 */
762 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800763 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100764 };
765 /* via 10.10.10.2 */
766 ip46_address_t nh_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800767 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100768 };
769
Neale Rannsf12a83f2017-04-18 09:09:40 -0700770 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800771 pool_elts(load_balance_map_pool));
Neale Rannsf12a83f2017-04-18 09:09:40 -0700772
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100773 tm = &test_main;
774
Neale Ranns994dab42017-04-18 12:56:45 -0700775 /* record the nubmer of load-balances in use before we start */
776 lb_count = pool_elts(load_balance_pool);
777
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100778 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700779 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
780 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100781
782 for (ii = 0; ii < 4; ii++)
783 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800784 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100785 }
786
787 fib_prefix_t pfx_0_0_0_0_s_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800788 .fp_len = 0,
789 .fp_proto = FIB_PROTOCOL_IP4,
790 .fp_addr = {
791 .ip4 = {
792 {0}
793 },
794 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100795 };
796
797 fib_prefix_t pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800798 .fp_len = 0,
799 .fp_proto = FIB_PROTOCOL_IP4,
800 .fp_addr = {
801 .ip4 = {
802 {0}
803 },
804 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100805 };
806
807 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
808
809 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
810 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
811 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800812 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100813
814 pfx.fp_len = 32;
815 fei = fib_table_lookup(fib_index, &pfx);
816 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
817 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800818 "all 0s route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100819
820 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
821 pfx.fp_len = 32;
822 fei = fib_table_lookup(fib_index, &pfx);
823 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
824 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800825 "all 1s route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100826
827 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
828 pfx.fp_len = 8;
829 fei = fib_table_lookup(fib_index, &pfx);
830 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
831 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800832 "all-mcast route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100833
834 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
835 pfx.fp_len = 8;
836 fei = fib_table_lookup(fib_index, &pfx);
837 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
838 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800839 "class-e route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100840
841 /*
842 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
843 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000844 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
845 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100846 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000847#define ENBR (5+5+2)
Jakub Grajciar7b867a82017-12-08 16:28:42 +0100848
849 u32 PNBR = 5+5+2+4;
850
851 /*
852 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
853 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100854 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000855 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800856 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000857 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800858 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100859
860 /*
861 * add interface routes.
862 * validate presence of /24 attached and /32 recieve.
863 * test for the presence of the receive address in the glean and local adj
864 */
865 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800866 .fp_len = 24,
867 .fp_proto = FIB_PROTOCOL_IP4,
868 .fp_addr = {
869 .ip4 = {
870 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
871 },
872 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100873 };
874
875 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800876 FIB_SOURCE_INTERFACE,
877 (FIB_ENTRY_FLAG_CONNECTED |
878 FIB_ENTRY_FLAG_ATTACHED),
879 DPO_PROTO_IP4,
880 NULL,
881 tm->hw[0]->sw_if_index,
882 ~0, // invalid fib index
883 1, // weight
884 NULL,
885 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100886 fei = fib_table_lookup(fib_index, &local_pfx);
887 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
888 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -0800889 fib_entry_get_flags(fei)),
890 "Flags set on attached interface");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100891
892 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700893 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
894 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100895 adj = adj_get(ai);
896 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -0800897 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100898 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -0800899 &adj->sub_type.glean.receive_addr)),
900 "attached interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100901
902 local_pfx.fp_len = 32;
903 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800904 FIB_SOURCE_INTERFACE,
905 (FIB_ENTRY_FLAG_CONNECTED |
906 FIB_ENTRY_FLAG_LOCAL),
907 DPO_PROTO_IP4,
908 NULL,
909 tm->hw[0]->sw_if_index,
910 ~0, // invalid fib index
911 1, // weight
912 NULL,
913 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100914 fei = fib_table_lookup(fib_index, &local_pfx);
915 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -0800916 fib_entry_get_flags(fei)),
917 "Flags set on local interface");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100918
919 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
920
921 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -0800922 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
923 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100924 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
925 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -0800926 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100927 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
928
929 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -0800930 &rd->rd_addr)),
931 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100932
933 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
934 FIB_PROTOCOL_IP4,
935 FIB_SOURCE_INTERFACE)),
936 "2 Interface Source'd prefixes");
937
938 /*
939 * +2 interface routes +2 non-shared path-lists
940 */
941 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000942 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800943 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000944 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800945 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100946
947 /*
948 * Modify the default route to be via an adj not yet known.
949 * this sources the defalut route with the API source, which is
950 * a higher preference to the DEFAULT_ROUTE source
951 */
952 pfx.fp_addr.ip4.as_u32 = 0;
953 pfx.fp_len = 0;
954 fib_table_entry_path_add(fib_index, &pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800955 FIB_SOURCE_API,
956 FIB_ENTRY_FLAG_NONE,
957 DPO_PROTO_IP4,
958 &nh_10_10_10_1,
959 tm->hw[0]->sw_if_index,
960 ~0, // invalid fib index
961 1,
962 NULL,
963 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100964 fei = fib_table_lookup(fib_index, &pfx);
965 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800966 "Flags set on API route");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100967
968 FIB_TEST((fei == dfrt), "default route same index");
969 ai = fib_entry_get_adj(fei);
970 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
971 adj = adj_get(ai);
972 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -0800973 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100974 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800975 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100976 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
977 FIB_PROTOCOL_IP4,
978 FIB_SOURCE_API)),
979 "1 API Source'd prefixes");
980
981 /*
982 * find the adj in the shared db
983 */
984 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -0800985 VNET_LINK_IP4,
986 &nh_10_10_10_1,
987 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100988 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
989 adj_unlock(locked_ai);
990
991 /*
992 * +1 shared path-list
993 */
994 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800995 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000996 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800997 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000998 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800999 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001000
1001 /*
1002 * remove the API source from the default route. We expected
1003 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
1004 */
1005 pfx.fp_addr.ip4.as_u32 = 0;
1006 pfx.fp_len = 0;
1007 fib_table_entry_path_remove(fib_index, &pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08001008 FIB_SOURCE_API,
1009 DPO_PROTO_IP4,
1010 &nh_10_10_10_1,
1011 tm->hw[0]->sw_if_index,
1012 ~0, // non-recursive path, so no FIB index
1013 1,
1014 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001015
1016 fei = fib_table_lookup(fib_index, &pfx);
1017
1018 FIB_TEST((fei == dfrt), "default route same index");
1019 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001020 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001021
1022 /*
1023 * -1 shared-path-list
1024 */
1025 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001026 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001027 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001028 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001029 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001030
1031 /*
1032 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
1033 */
1034 fib_prefix_t pfx_10_10_10_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001035 .fp_len = 32,
1036 .fp_proto = FIB_PROTOCOL_IP4,
1037 .fp_addr = {
1038 /* 10.10.10.1 */
1039 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1040 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001041 };
1042 fib_prefix_t pfx_10_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001043 .fp_len = 32,
1044 .fp_proto = FIB_PROTOCOL_IP4,
1045 .fp_addr = {
1046 /* 10.10.10.2 */
1047 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1048 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001049 };
1050 fib_prefix_t pfx_11_11_11_11_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001051 .fp_len = 32,
1052 .fp_proto = FIB_PROTOCOL_IP4,
1053 .fp_addr = {
1054 /* 11.11.11.11 */
1055 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1056 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001057 };
1058 u8 eth_addr[] = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001059 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001060 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001061
Neale Ranns3ee44042016-10-03 13:05:48 +01001062 ip46_address_t nh_12_12_12_12 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001063 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
Neale Ranns3ee44042016-10-03 13:05:48 +01001064 };
1065 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001066
1067 /*
1068 * Add a route via an incomplete ADJ. then complete the ADJ
1069 * Expect the route LB is updated to use complete adj type.
1070 */
1071 fei = fib_table_entry_update_one_path(fib_index,
1072 &pfx_11_11_11_11_s_32,
1073 FIB_SOURCE_API,
1074 FIB_ENTRY_FLAG_ATTACHED,
Neale Ranns2303cb12018-02-21 04:57:17 -08001075 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001076 &pfx_10_10_10_1_s_32.fp_addr,
1077 tm->hw[0]->sw_if_index,
1078 ~0, // invalid fib index
1079 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001080 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001081 FIB_ROUTE_PATH_FLAG_NONE);
1082
1083 dpo = fib_entry_contribute_ip_forwarding(fei);
1084 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1085 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1086 "11.11.11.11/32 via incomplete adj");
1087
1088 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001089 VNET_LINK_IP4,
1090 &pfx_10_10_10_1_s_32.fp_addr,
1091 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001092 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1093 adj = adj_get(ai_01);
1094 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001095 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001096 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001097 &adj->sub_type.nbr.next_hop)),
1098 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001099
Neale Rannsb80c5362016-10-08 13:03:40 +01001100 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001101 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001102 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001103 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001104 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001105 &adj->sub_type.nbr.next_hop)),
1106 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001107 ai = fib_entry_get_adj(fei);
1108 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1109
1110 dpo = fib_entry_contribute_ip_forwarding(fei);
1111 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1112 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1113 "11.11.11.11/32 via complete adj");
Neale Ranns2303cb12018-02-21 04:57:17 -08001114 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1115 tm->hw[0]->sw_if_index),
1116 "RPF list for adj-fib contains adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001117
1118 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001119 VNET_LINK_IP4,
1120 &nh_12_12_12_12,
1121 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01001122 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1123 adj = adj_get(ai_12_12_12_12);
1124 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001125 "adj is incomplete");
Neale Ranns3ee44042016-10-03 13:05:48 +01001126 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
Neale Ranns2303cb12018-02-21 04:57:17 -08001127 &adj->sub_type.nbr.next_hop)),
1128 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001129 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001130 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001131 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001132 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001133
1134 /*
1135 * add the adj fib
1136 */
Neale Ranns81424992017-05-18 03:03:22 -07001137 fei = fib_table_entry_path_add(fib_index,
1138 &pfx_10_10_10_1_s_32,
1139 FIB_SOURCE_ADJ,
1140 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001141 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001142 &pfx_10_10_10_1_s_32.fp_addr,
1143 tm->hw[0]->sw_if_index,
1144 ~0, // invalid fib index
1145 1,
1146 NULL,
1147 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001148 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001149 "Flags set on adj-fib");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001150 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001151 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001152
1153 fib_table_entry_path_remove(fib_index,
1154 &pfx_11_11_11_11_s_32,
1155 FIB_SOURCE_API,
Neale Ranns2303cb12018-02-21 04:57:17 -08001156 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001157 &pfx_10_10_10_1_s_32.fp_addr,
1158 tm->hw[0]->sw_if_index,
1159 ~0, // invalid fib index
1160 1,
1161 FIB_ROUTE_PATH_FLAG_NONE);
1162
1163 eth_addr[5] = 0xb2;
1164
1165 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001166 VNET_LINK_IP4,
1167 &pfx_10_10_10_2_s_32.fp_addr,
1168 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001169 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1170 adj = adj_get(ai_02);
1171 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001172 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001173 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001174 &adj->sub_type.nbr.next_hop)),
1175 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001176
Neale Rannsb80c5362016-10-08 13:03:40 +01001177 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001178 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001179 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001180 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001181 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001182 &adj->sub_type.nbr.next_hop)),
1183 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001184 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1185
Neale Ranns81424992017-05-18 03:03:22 -07001186 fib_table_entry_path_add(fib_index,
1187 &pfx_10_10_10_2_s_32,
1188 FIB_SOURCE_ADJ,
1189 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001190 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001191 &pfx_10_10_10_2_s_32.fp_addr,
1192 tm->hw[0]->sw_if_index,
1193 ~0, // invalid fib index
1194 1,
1195 NULL,
1196 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001197
1198 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1199 ai = fib_entry_get_adj(fei);
1200 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1201
1202 /*
1203 * +2 adj-fibs, and their non-shared path-lists
1204 */
1205 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001206 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001207 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001208 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001209 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001210
1211 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001212 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001213 */
1214 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001215 .fp_len = 32,
1216 .fp_proto = FIB_PROTOCOL_IP4,
1217 .fp_addr = {
1218 /* 1.1.1.1/32 */
1219 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1220 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001221 };
1222
1223 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001224 &pfx_1_1_1_1_s_32,
1225 FIB_SOURCE_API,
1226 FIB_ENTRY_FLAG_NONE,
1227 DPO_PROTO_IP4,
1228 &nh_10_10_10_1,
1229 tm->hw[0]->sw_if_index,
1230 ~0, // invalid fib index
1231 1,
1232 NULL,
1233 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001234 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1235 ai = fib_entry_get_adj(fei);
1236 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1237
1238 /*
1239 * +1 entry and a shared path-list
1240 */
1241 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001242 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001243 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001244 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001245 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001246
1247 /* 1.1.2.0/24 */
1248 fib_prefix_t pfx_1_1_2_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001249 .fp_len = 24,
1250 .fp_proto = FIB_PROTOCOL_IP4,
1251 .fp_addr = {
1252 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1253 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001254 };
1255
1256 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001257 &pfx_1_1_2_0_s_24,
1258 FIB_SOURCE_API,
1259 FIB_ENTRY_FLAG_NONE,
1260 DPO_PROTO_IP4,
1261 &nh_10_10_10_1,
1262 tm->hw[0]->sw_if_index,
1263 ~0, // invalid fib index
1264 1,
1265 NULL,
1266 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001267 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1268 ai = fib_entry_get_adj(fei);
1269 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1270
1271 /*
1272 * +1 entry only
1273 */
1274 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001275 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001276 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001277 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001278 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001279
1280 /*
1281 * modify 1.1.2.0/24 to use multipath.
1282 */
1283 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001284 &pfx_1_1_2_0_s_24,
1285 FIB_SOURCE_API,
1286 FIB_ENTRY_FLAG_NONE,
1287 DPO_PROTO_IP4,
1288 &nh_10_10_10_2,
1289 tm->hw[0]->sw_if_index,
1290 ~0, // invalid fib index
1291 1,
1292 NULL,
1293 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001294 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1295 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08001296 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1297 1, tm->hw[0]->sw_if_index),
1298 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001299
1300 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1301 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1302 FIB_TEST((ai_01 == dpo1->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001303 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001304 ai_01, dpo1->dpoi_index);
1305
1306 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1307 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1308 FIB_TEST((ai_02 == dpo1->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001309 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001310
1311 /*
1312 * +1 shared-pathlist
1313 */
1314 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001315 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001316 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001317 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001318 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001319
1320 /*
1321 * revert the modify
1322 */
1323 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001324 &pfx_1_1_2_0_s_24,
1325 FIB_SOURCE_API,
1326 DPO_PROTO_IP4,
1327 &nh_10_10_10_2,
1328 tm->hw[0]->sw_if_index,
1329 ~0,
1330 1,
1331 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001332 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001333 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08001334 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1335 1, tm->hw[0]->sw_if_index),
1336 "RPF list for 1.1.2.0/24 contains one adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001337
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001338 ai = fib_entry_get_adj(fei);
1339 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1340
1341 /*
1342 * +1 shared-pathlist
1343 */
1344 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001345 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001346 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001347 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001348 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001349 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001350
1351 /*
1352 * Add 2 recursive routes:
1353 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1354 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1355 */
1356 fib_prefix_t bgp_100_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001357 .fp_len = 32,
1358 .fp_proto = FIB_PROTOCOL_IP4,
1359 .fp_addr = {
1360 /* 100.100.100.100/32 */
1361 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1362 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001363 };
1364 /* via 1.1.1.1 */
1365 ip46_address_t nh_1_1_1_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001366 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001367 };
1368
Neale Ranns3ee44042016-10-03 13:05:48 +01001369 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001370 &bgp_100_pfx,
1371 FIB_SOURCE_API,
1372 FIB_ENTRY_FLAG_NONE,
1373 DPO_PROTO_IP4,
1374 &nh_1_1_1_1,
1375 ~0, // no index provided.
1376 fib_index, // nexthop in same fib as route
1377 1,
1378 NULL,
1379 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001380
Neale Ranns3ee44042016-10-03 13:05:48 +01001381 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
Neale Ranns2303cb12018-02-21 04:57:17 -08001382 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1383 tm->hw[0]->sw_if_index),
1384 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001385
1386 /*
1387 * +1 entry and +1 shared-path-list
1388 */
1389 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001390 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001391 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001392 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001393 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001394 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001395
1396 fib_prefix_t bgp_101_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001397 .fp_len = 32,
1398 .fp_proto = FIB_PROTOCOL_IP4,
1399 .fp_addr = {
1400 /* 100.100.100.101/32 */
1401 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1402 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001403 };
1404
1405 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001406 &bgp_101_pfx,
1407 FIB_SOURCE_API,
1408 FIB_ENTRY_FLAG_NONE,
1409 DPO_PROTO_IP4,
1410 &nh_1_1_1_1,
1411 ~0, // no index provided.
1412 fib_index, // nexthop in same fib as route
1413 1,
1414 NULL,
1415 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001416
Neale Ranns3ee44042016-10-03 13:05:48 +01001417 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
Neale Ranns2303cb12018-02-21 04:57:17 -08001418 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1419 tm->hw[0]->sw_if_index),
1420 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001421
1422 /*
1423 * +1 entry, but the recursive path-list is shared.
1424 */
1425 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001426 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001427 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001428 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001429 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001430 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001431
1432 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001433 * An special route; one where the user (me) provides the
1434 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001435 */
1436 fib_prefix_t ex_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001437 .fp_len = 32,
1438 .fp_proto = FIB_PROTOCOL_IP4,
1439 .fp_addr = {
1440 /* 4.4.4.4/32 */
1441 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1442 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001443 };
1444
1445 fib_table_entry_special_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001446 &ex_pfx,
1447 FIB_SOURCE_SPECIAL,
1448 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001449 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001450 dpo = fib_entry_contribute_ip_forwarding(fei);
1451 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1452 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08001453 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001454
1455 fib_table_entry_special_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001456 &ex_pfx,
1457 FIB_SOURCE_SPECIAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001458 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08001459 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1460 "Exclusive reoute removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001461
1462 /*
1463 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1464 * adjacency through which the route will resovle
1465 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001466 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001467
1468 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1469 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001470 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001471 LOOKUP_INPUT_DST_ADDR,
1472 LOOKUP_TABLE_FROM_CONFIG,
1473 &ex_dpo);
1474
1475 fib_table_entry_special_dpo_add(fib_index,
1476 &ex_pfx,
1477 FIB_SOURCE_SPECIAL,
1478 FIB_ENTRY_FLAG_EXCLUSIVE,
1479 &ex_dpo);
1480 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1481 dpo = fib_entry_contribute_ip_forwarding(fei);
1482 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001483 "exclusive remote uses lookup DPO");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001484
Neale Ranns948e00f2016-10-20 13:39:34 +01001485 /*
1486 * update the exclusive to use a different DPO
1487 */
Neale Ranns450cd302016-11-09 17:49:42 +00001488 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001489 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1490 &ex_dpo);
Neale Ranns948e00f2016-10-20 13:39:34 +01001491 fib_table_entry_special_dpo_update(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001492 &ex_pfx,
1493 FIB_SOURCE_SPECIAL,
1494 FIB_ENTRY_FLAG_EXCLUSIVE,
1495 &ex_dpo);
Neale Ranns948e00f2016-10-20 13:39:34 +01001496 dpo = fib_entry_contribute_ip_forwarding(fei);
1497 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001498 "exclusive remote uses now uses NULL DPO");
Neale Ranns948e00f2016-10-20 13:39:34 +01001499
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001500 fib_table_entry_special_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001501 &ex_pfx,
1502 FIB_SOURCE_SPECIAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001503 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08001504 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1505 "Exclusive reoute removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001506 dpo_reset(&ex_dpo);
1507
1508 /*
1509 * Add a recursive route:
1510 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1511 */
1512 fib_prefix_t bgp_200_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001513 .fp_len = 32,
1514 .fp_proto = FIB_PROTOCOL_IP4,
1515 .fp_addr = {
1516 /* 200.200.200.200/32 */
1517 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1518 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001519 };
1520 /* via 1.1.1.2 */
1521 fib_prefix_t pfx_1_1_1_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001522 .fp_len = 32,
1523 .fp_proto = FIB_PROTOCOL_IP4,
1524 .fp_addr = {
1525 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1526 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001527 };
1528
Neale Ranns57b58602017-07-15 07:37:25 -07001529 fei = fib_table_entry_path_add(fib_index,
1530 &bgp_200_pfx,
1531 FIB_SOURCE_API,
1532 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001533 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001534 &pfx_1_1_1_2_s_32.fp_addr,
1535 ~0, // no index provided.
1536 fib_index, // nexthop in same fib as route
1537 1,
1538 NULL,
1539 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001540
Neale Ranns57b58602017-07-15 07:37:25 -07001541 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1542 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001543
1544 /*
1545 * the adj should be recursive via drop, since the route resolves via
Neale Ranns2303cb12018-02-21 04:57:17 -08001546 * the default route, which is itself a DROP
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001547 */
1548 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1549 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1550 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns2303cb12018-02-21 04:57:17 -08001551 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1552 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001553
1554 /*
1555 * +2 entry and +1 shared-path-list
1556 */
1557 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001558 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001559 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001560 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001561 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001562 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001563
1564 /*
1565 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001566 * The paths are sort by NH first. in this case the the path with greater
1567 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001568 */
1569 fib_prefix_t pfx_1_2_3_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001570 .fp_len = 32,
1571 .fp_proto = FIB_PROTOCOL_IP4,
1572 .fp_addr = {
1573 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1574 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001575 };
1576 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001577 &pfx_1_2_3_4_s_32,
1578 FIB_SOURCE_API,
1579 FIB_ENTRY_FLAG_NONE,
1580 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001581 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001582 tm->hw[0]->sw_if_index,
1583 ~0,
1584 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001585 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001586 FIB_ROUTE_PATH_FLAG_NONE);
1587 fei = fib_table_entry_path_add(fib_index,
1588 &pfx_1_2_3_4_s_32,
1589 FIB_SOURCE_API,
1590 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001591 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001592 &nh_12_12_12_12,
1593 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001594 ~0,
1595 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001596 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001597 FIB_ROUTE_PATH_FLAG_NONE);
1598
1599 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1600 dpo = fib_entry_contribute_ip_forwarding(fei);
1601 lb = load_balance_get(dpo->dpoi_index);
1602 FIB_TEST((lb->lb_n_buckets == 4),
1603 "1.2.3.4/32 LB has %d bucket",
1604 lb->lb_n_buckets);
1605
Neale Ranns3ee44042016-10-03 13:05:48 +01001606 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1607 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1608 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1609 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001610
Neale Ranns2303cb12018-02-21 04:57:17 -08001611 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1612 tm->hw[0]->sw_if_index,
1613 tm->hw[1]->sw_if_index),
1614 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01001615
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001616
1617 /*
1618 * Unequal Cost load-balance. 4:1 ratio.
1619 * fits in a 16 bucket LB with ratio 13:3
1620 */
1621 fib_prefix_t pfx_1_2_3_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001622 .fp_len = 32,
1623 .fp_proto = FIB_PROTOCOL_IP4,
1624 .fp_addr = {
1625 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1626 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001627 };
1628 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001629 &pfx_1_2_3_5_s_32,
1630 FIB_SOURCE_API,
1631 FIB_ENTRY_FLAG_NONE,
1632 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001633 &nh_12_12_12_12,
1634 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001635 ~0,
1636 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001637 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001638 FIB_ROUTE_PATH_FLAG_NONE);
1639 fei = fib_table_entry_path_add(fib_index,
1640 &pfx_1_2_3_5_s_32,
1641 FIB_SOURCE_API,
1642 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001643 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001644 &nh_10_10_10_1,
1645 tm->hw[0]->sw_if_index,
1646 ~0,
1647 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001648 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001649 FIB_ROUTE_PATH_FLAG_NONE);
1650
1651 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1652 dpo = fib_entry_contribute_ip_forwarding(fei);
1653 lb = load_balance_get(dpo->dpoi_index);
1654 FIB_TEST((lb->lb_n_buckets == 16),
1655 "1.2.3.5/32 LB has %d bucket",
1656 lb->lb_n_buckets);
1657
1658 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1659 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1660 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1661 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1662 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1663 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1664 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1665 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1666 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1667 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1668 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1669 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1670 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001671 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1672 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1673 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1674
Neale Ranns2303cb12018-02-21 04:57:17 -08001675 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1676 tm->hw[0]->sw_if_index,
1677 tm->hw[1]->sw_if_index),
1678 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01001679
1680 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001681 * Test UCMP with a large weight skew - this produces load-balance objects with large
1682 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1683 * laso testing the LB in placce modify code when number of buckets is large.
1684 */
1685 fib_prefix_t pfx_6_6_6_6_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001686 .fp_len = 32,
1687 .fp_proto = FIB_PROTOCOL_IP4,
1688 .fp_addr = {
1689 /* 1.1.1.1/32 */
1690 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1691 },
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001692 };
Neale Ranns81424992017-05-18 03:03:22 -07001693 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001694 .type = FT_LB_ADJ,
1695 .adj = {
1696 .adj = ai_01,
1697 },
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001698 };
Neale Ranns81424992017-05-18 03:03:22 -07001699 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001700 .type = FT_LB_ADJ,
1701 .adj = {
1702 .adj = ai_02,
1703 },
1704 };
1705 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1706 .type = FT_LB_ADJ,
1707 .adj = {
1708 .adj = ai_12_12_12_12,
1709 },
1710 };
1711 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001712 &pfx_6_6_6_6_s_32,
1713 FIB_SOURCE_API,
1714 FIB_ENTRY_FLAG_NONE,
1715 DPO_PROTO_IP4,
1716 &nh_10_10_10_1,
1717 tm->hw[0]->sw_if_index,
1718 ~0, // invalid fib index
1719 0, // zero weigth
1720 NULL,
1721 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001722
1723 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001724 FIB_TEST(!fib_test_validate_entry(fei,
1725 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1726 1,
1727 &ip_o_10_10_10_1),
1728 "6.6.6.6/32 via 10.10.10.1");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001729
1730 fib_table_entry_path_add(fib_index,
1731 &pfx_6_6_6_6_s_32,
1732 FIB_SOURCE_API,
1733 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001734 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001735 &nh_10_10_10_2,
1736 tm->hw[0]->sw_if_index,
1737 ~0, // invalid fib index
1738 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001739 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001740 FIB_ROUTE_PATH_FLAG_NONE);
1741
1742 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001743 FIB_TEST(!fib_test_validate_entry(fei,
1744 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1745 64,
1746 &ip_o_10_10_10_2,
1747 &ip_o_10_10_10_2,
1748 &ip_o_10_10_10_2,
1749 &ip_o_10_10_10_2,
1750 &ip_o_10_10_10_2,
1751 &ip_o_10_10_10_2,
1752 &ip_o_10_10_10_2,
1753 &ip_o_10_10_10_2,
1754 &ip_o_10_10_10_2,
1755 &ip_o_10_10_10_2,
1756 &ip_o_10_10_10_2,
1757 &ip_o_10_10_10_2,
1758 &ip_o_10_10_10_2,
1759 &ip_o_10_10_10_2,
1760 &ip_o_10_10_10_2,
1761 &ip_o_10_10_10_2,
1762 &ip_o_10_10_10_2,
1763 &ip_o_10_10_10_2,
1764 &ip_o_10_10_10_2,
1765 &ip_o_10_10_10_2,
1766 &ip_o_10_10_10_2,
1767 &ip_o_10_10_10_2,
1768 &ip_o_10_10_10_2,
1769 &ip_o_10_10_10_2,
1770 &ip_o_10_10_10_2,
1771 &ip_o_10_10_10_2,
1772 &ip_o_10_10_10_2,
1773 &ip_o_10_10_10_2,
1774 &ip_o_10_10_10_2,
1775 &ip_o_10_10_10_2,
1776 &ip_o_10_10_10_2,
1777 &ip_o_10_10_10_2,
1778 &ip_o_10_10_10_2,
1779 &ip_o_10_10_10_2,
1780 &ip_o_10_10_10_2,
1781 &ip_o_10_10_10_2,
1782 &ip_o_10_10_10_2,
1783 &ip_o_10_10_10_2,
1784 &ip_o_10_10_10_2,
1785 &ip_o_10_10_10_2,
1786 &ip_o_10_10_10_2,
1787 &ip_o_10_10_10_2,
1788 &ip_o_10_10_10_2,
1789 &ip_o_10_10_10_2,
1790 &ip_o_10_10_10_2,
1791 &ip_o_10_10_10_2,
1792 &ip_o_10_10_10_2,
1793 &ip_o_10_10_10_2,
1794 &ip_o_10_10_10_2,
1795 &ip_o_10_10_10_2,
1796 &ip_o_10_10_10_2,
1797 &ip_o_10_10_10_2,
1798 &ip_o_10_10_10_2,
1799 &ip_o_10_10_10_2,
1800 &ip_o_10_10_10_2,
1801 &ip_o_10_10_10_2,
1802 &ip_o_10_10_10_2,
1803 &ip_o_10_10_10_2,
1804 &ip_o_10_10_10_2,
1805 &ip_o_10_10_10_2,
1806 &ip_o_10_10_10_2,
1807 &ip_o_10_10_10_2,
1808 &ip_o_10_10_10_2,
1809 &ip_o_10_10_10_1),
1810 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001811
1812 fib_table_entry_path_add(fib_index,
1813 &pfx_6_6_6_6_s_32,
1814 FIB_SOURCE_API,
1815 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001816 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001817 &nh_12_12_12_12,
1818 tm->hw[1]->sw_if_index,
1819 ~0, // invalid fib index
1820 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001821 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001822 FIB_ROUTE_PATH_FLAG_NONE);
1823
1824 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001825 FIB_TEST(!fib_test_validate_entry(fei,
1826 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1827 128,
1828 &ip_o_10_10_10_1,
1829 &ip_o_10_10_10_2,
1830 &ip_o_10_10_10_2,
1831 &ip_o_10_10_10_2,
1832 &ip_o_10_10_10_2,
1833 &ip_o_10_10_10_2,
1834 &ip_o_10_10_10_2,
1835 &ip_o_10_10_10_2,
1836 &ip_o_10_10_10_2,
1837 &ip_o_10_10_10_2,
1838 &ip_o_10_10_10_2,
1839 &ip_o_10_10_10_2,
1840 &ip_o_10_10_10_2,
1841 &ip_o_10_10_10_2,
1842 &ip_o_10_10_10_2,
1843 &ip_o_10_10_10_2,
1844 &ip_o_10_10_10_2,
1845 &ip_o_10_10_10_2,
1846 &ip_o_10_10_10_2,
1847 &ip_o_10_10_10_2,
1848 &ip_o_10_10_10_2,
1849 &ip_o_10_10_10_2,
1850 &ip_o_10_10_10_2,
1851 &ip_o_10_10_10_2,
1852 &ip_o_10_10_10_2,
1853 &ip_o_10_10_10_2,
1854 &ip_o_10_10_10_2,
1855 &ip_o_10_10_10_2,
1856 &ip_o_10_10_10_2,
1857 &ip_o_10_10_10_2,
1858 &ip_o_10_10_10_2,
1859 &ip_o_10_10_10_2,
1860 &ip_o_10_10_10_2,
1861 &ip_o_10_10_10_2,
1862 &ip_o_10_10_10_2,
1863 &ip_o_10_10_10_2,
1864 &ip_o_10_10_10_2,
1865 &ip_o_10_10_10_2,
1866 &ip_o_10_10_10_2,
1867 &ip_o_10_10_10_2,
1868 &ip_o_10_10_10_2,
1869 &ip_o_10_10_10_2,
1870 &ip_o_10_10_10_2,
1871 &ip_o_10_10_10_2,
1872 &ip_o_10_10_10_2,
1873 &ip_o_10_10_10_2,
1874 &ip_o_10_10_10_2,
1875 &ip_o_10_10_10_2,
1876 &ip_o_10_10_10_2,
1877 &ip_o_10_10_10_2,
1878 &ip_o_10_10_10_2,
1879 &ip_o_10_10_10_2,
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_6_6_6_6_o_12_12_12_12,
1894 &ip_6_6_6_6_o_12_12_12_12,
1895 &ip_6_6_6_6_o_12_12_12_12,
1896 &ip_6_6_6_6_o_12_12_12_12,
1897 &ip_6_6_6_6_o_12_12_12_12,
1898 &ip_6_6_6_6_o_12_12_12_12,
1899 &ip_6_6_6_6_o_12_12_12_12,
1900 &ip_6_6_6_6_o_12_12_12_12,
1901 &ip_6_6_6_6_o_12_12_12_12,
1902 &ip_6_6_6_6_o_12_12_12_12,
1903 &ip_6_6_6_6_o_12_12_12_12,
1904 &ip_6_6_6_6_o_12_12_12_12,
1905 &ip_6_6_6_6_o_12_12_12_12,
1906 &ip_6_6_6_6_o_12_12_12_12,
1907 &ip_6_6_6_6_o_12_12_12_12,
1908 &ip_6_6_6_6_o_12_12_12_12,
1909 &ip_6_6_6_6_o_12_12_12_12,
1910 &ip_6_6_6_6_o_12_12_12_12,
1911 &ip_6_6_6_6_o_12_12_12_12,
1912 &ip_6_6_6_6_o_12_12_12_12,
1913 &ip_6_6_6_6_o_12_12_12_12,
1914 &ip_6_6_6_6_o_12_12_12_12,
1915 &ip_6_6_6_6_o_12_12_12_12,
1916 &ip_6_6_6_6_o_12_12_12_12,
1917 &ip_6_6_6_6_o_12_12_12_12,
1918 &ip_6_6_6_6_o_12_12_12_12,
1919 &ip_6_6_6_6_o_12_12_12_12,
1920 &ip_6_6_6_6_o_12_12_12_12,
1921 &ip_6_6_6_6_o_12_12_12_12,
1922 &ip_6_6_6_6_o_12_12_12_12,
1923 &ip_6_6_6_6_o_12_12_12_12,
1924 &ip_6_6_6_6_o_12_12_12_12,
1925 &ip_6_6_6_6_o_12_12_12_12,
1926 &ip_6_6_6_6_o_12_12_12_12,
1927 &ip_6_6_6_6_o_12_12_12_12,
1928 &ip_6_6_6_6_o_12_12_12_12,
1929 &ip_6_6_6_6_o_12_12_12_12,
1930 &ip_6_6_6_6_o_12_12_12_12,
1931 &ip_6_6_6_6_o_12_12_12_12,
1932 &ip_6_6_6_6_o_12_12_12_12,
1933 &ip_6_6_6_6_o_12_12_12_12,
1934 &ip_6_6_6_6_o_12_12_12_12,
1935 &ip_6_6_6_6_o_12_12_12_12,
1936 &ip_6_6_6_6_o_12_12_12_12,
1937 &ip_6_6_6_6_o_12_12_12_12,
1938 &ip_6_6_6_6_o_12_12_12_12,
1939 &ip_6_6_6_6_o_12_12_12_12,
1940 &ip_6_6_6_6_o_12_12_12_12,
1941 &ip_6_6_6_6_o_12_12_12_12,
1942 &ip_6_6_6_6_o_12_12_12_12,
1943 &ip_6_6_6_6_o_12_12_12_12,
1944 &ip_6_6_6_6_o_12_12_12_12,
1945 &ip_6_6_6_6_o_12_12_12_12,
1946 &ip_6_6_6_6_o_12_12_12_12,
1947 &ip_6_6_6_6_o_12_12_12_12,
1948 &ip_6_6_6_6_o_12_12_12_12,
1949 &ip_6_6_6_6_o_12_12_12_12,
1950 &ip_6_6_6_6_o_12_12_12_12,
1951 &ip_6_6_6_6_o_12_12_12_12,
1952 &ip_6_6_6_6_o_12_12_12_12,
1953 &ip_6_6_6_6_o_12_12_12_12,
1954 &ip_6_6_6_6_o_12_12_12_12,
1955 &ip_6_6_6_6_o_12_12_12_12),
1956 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001957
1958 fib_table_entry_path_remove(fib_index,
1959 &pfx_6_6_6_6_s_32,
1960 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001961 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001962 &nh_12_12_12_12,
1963 tm->hw[1]->sw_if_index,
1964 ~0, // invalid fib index
1965 100,
1966 FIB_ROUTE_PATH_FLAG_NONE);
1967
1968 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001969 FIB_TEST(!fib_test_validate_entry(fei,
1970 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1971 64,
1972 &ip_o_10_10_10_2,
1973 &ip_o_10_10_10_2,
1974 &ip_o_10_10_10_2,
1975 &ip_o_10_10_10_2,
1976 &ip_o_10_10_10_2,
1977 &ip_o_10_10_10_2,
1978 &ip_o_10_10_10_2,
1979 &ip_o_10_10_10_2,
1980 &ip_o_10_10_10_2,
1981 &ip_o_10_10_10_2,
1982 &ip_o_10_10_10_2,
1983 &ip_o_10_10_10_2,
1984 &ip_o_10_10_10_2,
1985 &ip_o_10_10_10_2,
1986 &ip_o_10_10_10_2,
1987 &ip_o_10_10_10_2,
1988 &ip_o_10_10_10_2,
1989 &ip_o_10_10_10_2,
1990 &ip_o_10_10_10_2,
1991 &ip_o_10_10_10_2,
1992 &ip_o_10_10_10_2,
1993 &ip_o_10_10_10_2,
1994 &ip_o_10_10_10_2,
1995 &ip_o_10_10_10_2,
1996 &ip_o_10_10_10_2,
1997 &ip_o_10_10_10_2,
1998 &ip_o_10_10_10_2,
1999 &ip_o_10_10_10_2,
2000 &ip_o_10_10_10_2,
2001 &ip_o_10_10_10_2,
2002 &ip_o_10_10_10_2,
2003 &ip_o_10_10_10_2,
2004 &ip_o_10_10_10_2,
2005 &ip_o_10_10_10_2,
2006 &ip_o_10_10_10_2,
2007 &ip_o_10_10_10_2,
2008 &ip_o_10_10_10_2,
2009 &ip_o_10_10_10_2,
2010 &ip_o_10_10_10_2,
2011 &ip_o_10_10_10_2,
2012 &ip_o_10_10_10_2,
2013 &ip_o_10_10_10_2,
2014 &ip_o_10_10_10_2,
2015 &ip_o_10_10_10_2,
2016 &ip_o_10_10_10_2,
2017 &ip_o_10_10_10_2,
2018 &ip_o_10_10_10_2,
2019 &ip_o_10_10_10_2,
2020 &ip_o_10_10_10_2,
2021 &ip_o_10_10_10_2,
2022 &ip_o_10_10_10_2,
2023 &ip_o_10_10_10_2,
2024 &ip_o_10_10_10_2,
2025 &ip_o_10_10_10_2,
2026 &ip_o_10_10_10_2,
2027 &ip_o_10_10_10_2,
2028 &ip_o_10_10_10_2,
2029 &ip_o_10_10_10_2,
2030 &ip_o_10_10_10_2,
2031 &ip_o_10_10_10_2,
2032 &ip_o_10_10_10_2,
2033 &ip_o_10_10_10_2,
2034 &ip_o_10_10_10_2,
2035 &ip_o_10_10_10_1),
2036 "6.6.6.6/32 via 10.10.10.1 and 10.10.10.2 in 63:1 ratio");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002037
2038 fib_table_entry_path_remove(fib_index,
2039 &pfx_6_6_6_6_s_32,
2040 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002041 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002042 &nh_10_10_10_2,
2043 tm->hw[0]->sw_if_index,
2044 ~0, // invalid fib index
2045 100,
2046 FIB_ROUTE_PATH_FLAG_NONE);
2047
2048 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08002049 FIB_TEST(!fib_test_validate_entry(fei,
2050 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2051 1,
2052 &ip_o_10_10_10_1),
2053 "6.6.6.6/32 via 10.10.10.1");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002054
2055 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2056
2057 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002058 * A recursive via the two unequal cost entries
2059 */
2060 fib_prefix_t bgp_44_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002061 .fp_len = 32,
2062 .fp_proto = FIB_PROTOCOL_IP4,
2063 .fp_addr = {
2064 /* 200.200.200.201/32 */
2065 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2066 },
Neale Ranns3ee44042016-10-03 13:05:48 +01002067 };
2068 fei = fib_table_entry_path_add(fib_index,
2069 &bgp_44_s_32,
2070 FIB_SOURCE_API,
2071 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08002072 DPO_PROTO_IP4,
2073 &pfx_1_2_3_4_s_32.fp_addr,
Neale Ranns3ee44042016-10-03 13:05:48 +01002074 ~0,
2075 fib_index,
2076 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002077 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002078 FIB_ROUTE_PATH_FLAG_NONE);
2079 fei = fib_table_entry_path_add(fib_index,
2080 &bgp_44_s_32,
2081 FIB_SOURCE_API,
2082 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08002083 DPO_PROTO_IP4,
2084 &pfx_1_2_3_5_s_32.fp_addr,
Neale Ranns3ee44042016-10-03 13:05:48 +01002085 ~0,
2086 fib_index,
2087 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002088 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002089 FIB_ROUTE_PATH_FLAG_NONE);
2090
2091 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2092 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
Neale Ranns2303cb12018-02-21 04:57:17 -08002093 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2094 tm->hw[0]->sw_if_index,
2095 tm->hw[1]->sw_if_index),
2096 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01002097
2098 /*
2099 * test the uRPF check functions
2100 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002101 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002102 index_t urpfi;
2103
2104 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2105 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2106
2107 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002108 "uRPF check for 68.68.68.68/32 on %d OK",
2109 tm->hw[0]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01002110 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002111 "uRPF check for 68.68.68.68/32 on %d OK",
2112 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01002113 FIB_TEST(!fib_urpf_check(urpfi, 99),
Neale Ranns2303cb12018-02-21 04:57:17 -08002114 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2115 99);
Neale Ranns3ee44042016-10-03 13:05:48 +01002116 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002117
2118 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002119 &bgp_44_s_32,
2120 FIB_SOURCE_API);
2121 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002122 &pfx_1_2_3_5_s_32,
2123 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002124 fib_table_entry_delete(fib_index,
2125 &pfx_1_2_3_4_s_32,
2126 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002127
2128 /*
2129 * Add a recursive route:
2130 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2131 */
2132 fib_prefix_t bgp_201_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002133 .fp_len = 32,
2134 .fp_proto = FIB_PROTOCOL_IP4,
2135 .fp_addr = {
2136 /* 200.200.200.201/32 */
2137 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2138 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002139 };
2140 /* via 1.1.1.200 */
2141 fib_prefix_t pfx_1_1_1_200_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002142 .fp_len = 32,
2143 .fp_proto = FIB_PROTOCOL_IP4,
2144 .fp_addr = {
2145 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2146 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002147 };
2148
Neale Ranns57b58602017-07-15 07:37:25 -07002149 fei = fib_table_entry_path_add(fib_index,
2150 &bgp_201_pfx,
2151 FIB_SOURCE_API,
2152 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002153 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002154 &pfx_1_1_1_200_s_32.fp_addr,
2155 ~0, // no index provided.
2156 fib_index, // nexthop in same fib as route
2157 1,
2158 NULL,
2159 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002160
Neale Ranns57b58602017-07-15 07:37:25 -07002161 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2162 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002163
2164 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2165 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002166 "Flags set on RR via non-attached");
2167 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2168 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002169
2170 /*
2171 * +2 entry (BGP & RR) and +1 shared-path-list
2172 */
2173 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002174 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002175 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002176 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002177 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002178 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002179
2180 /*
2181 * insert a route that covers the missing 1.1.1.2/32. we epxect
2182 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2183 */
2184 fib_prefix_t pfx_1_1_1_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002185 .fp_len = 24,
2186 .fp_proto = FIB_PROTOCOL_IP4,
2187 .fp_addr = {
2188 /* 1.1.1.0/24 */
2189 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2190 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002191 };
2192
2193 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002194 &pfx_1_1_1_0_s_24,
2195 FIB_SOURCE_API,
2196 FIB_ENTRY_FLAG_NONE,
2197 DPO_PROTO_IP4,
2198 &nh_10_10_10_1,
2199 tm->hw[0]->sw_if_index,
2200 ~0, // invalid fib index
2201 1,
2202 NULL,
2203 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002204 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2205 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2206 ai = fib_entry_get_adj(fei);
2207 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2208 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2209 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2210 ai = fib_entry_get_adj(fei);
2211 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2212 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2213 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2214 ai = fib_entry_get_adj(fei);
2215 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2216
2217 /*
2218 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2219 */
2220 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002221 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002222 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002223 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002224 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002225 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002226
2227 /*
2228 * the recursive adj for 200.200.200.200 should be updated.
2229 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002230 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2231 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2232 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
Neale Ranns2303cb12018-02-21 04:57:17 -08002233 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2234 tm->hw[0]->sw_if_index),
2235 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002236
2237 /*
2238 * insert a more specific route than 1.1.1.0/24 that also covers the
Neale Ranns2303cb12018-02-21 04:57:17 -08002239 * missing 1.1.1.2/32, but not 1.1.1.200/32. we expect
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002240 * 200.200.200.200 to resolve through it.
2241 */
2242 fib_prefix_t pfx_1_1_1_0_s_28 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002243 .fp_len = 28,
2244 .fp_proto = FIB_PROTOCOL_IP4,
2245 .fp_addr = {
2246 /* 1.1.1.0/24 */
2247 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2248 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002249 };
2250
2251 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002252 &pfx_1_1_1_0_s_28,
2253 FIB_SOURCE_API,
2254 FIB_ENTRY_FLAG_NONE,
2255 DPO_PROTO_IP4,
2256 &nh_10_10_10_2,
2257 tm->hw[0]->sw_if_index,
2258 ~0, // invalid fib index
2259 1,
2260 NULL,
2261 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002262 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2263 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2264 ai = fib_entry_get_adj(fei);
2265 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2266
2267 /*
2268 * +1 entry. +1 shared path-list
2269 */
2270 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002271 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002272 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002273 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002274 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002275 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002276
2277 /*
2278 * the recursive adj for 200.200.200.200 should be updated.
2279 * 200.200.200.201 remains unchanged.
2280 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002281 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2282 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002283
2284 /*
2285 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2286 */
2287 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002288 &pfx_1_1_1_0_s_28,
2289 FIB_SOURCE_API,
2290 DPO_PROTO_IP4,
2291 &nh_10_10_10_2,
2292 tm->hw[0]->sw_if_index,
2293 ~0,
2294 1,
2295 FIB_ROUTE_PATH_FLAG_NONE);
2296 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2297 FIB_NODE_INDEX_INVALID),
2298 "1.1.1.0/28 removed");
2299 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2300 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2301 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002302 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2303 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002304
2305 /*
2306 * -1 entry. -1 shared path-list
2307 */
2308 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002309 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002310 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002311 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002312 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002313 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002314
2315 /*
2316 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2317 */
2318 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002319 &pfx_1_1_1_0_s_24,
2320 FIB_SOURCE_API,
2321 DPO_PROTO_IP4,
2322 &nh_10_10_10_1,
2323 tm->hw[0]->sw_if_index,
2324 ~0,
2325 1,
2326 FIB_ROUTE_PATH_FLAG_NONE);
2327 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2328 FIB_NODE_INDEX_INVALID),
2329 "1.1.1.0/24 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002330
2331 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2332 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002333 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002334 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002335 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002336 "1.1.1.200/32 route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002337
Neale Ranns57b58602017-07-15 07:37:25 -07002338 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2339 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2340 "201 is drop");
2341 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2342 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2343 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002344
2345 /*
2346 * -1 entry
2347 */
2348 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002349 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002350 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002351 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002352 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002353 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002354
2355 /*
2356 * insert the missing 1.1.1.2/32
2357 */
2358 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002359 &pfx_1_1_1_2_s_32,
2360 FIB_SOURCE_API,
2361 FIB_ENTRY_FLAG_NONE,
2362 DPO_PROTO_IP4,
2363 &nh_10_10_10_1,
2364 tm->hw[0]->sw_if_index,
2365 ~0, // invalid fib index
2366 1,
2367 NULL,
2368 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002369 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2370 ai = fib_entry_get_adj(fei);
2371 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2372
Neale Ranns57b58602017-07-15 07:37:25 -07002373 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2374 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2375 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002376 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002377
2378 /*
2379 * no change. 1.1.1.2/32 was already there RR sourced.
2380 */
2381 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002382 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002383 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002384 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002385 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002386 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002387
2388 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002389 * give 201 a resolved path.
2390 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2391 * only the latter contributes forwarding.
2392 */
2393 fei = fib_table_entry_path_add(fib_index,
2394 &bgp_201_pfx,
2395 FIB_SOURCE_API,
2396 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002397 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002398 &pfx_1_1_1_2_s_32.fp_addr,
2399 ~0,
2400 fib_index,
2401 1,
2402 NULL,
2403 FIB_ROUTE_PATH_FLAG_NONE);
2404 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2405 fib_table_entry_path_remove(fib_index,
2406 &bgp_201_pfx,
2407 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002408 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002409 &pfx_1_1_1_2_s_32.fp_addr,
2410 ~0,
2411 fib_index,
2412 1,
2413 FIB_ROUTE_PATH_FLAG_NONE);
2414
2415 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002416 * remove 200.200.200.201/32 which does not have a valid via FIB
2417 */
2418 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002419 &bgp_201_pfx,
2420 FIB_SOURCE_API,
2421 DPO_PROTO_IP4,
2422 &pfx_1_1_1_200_s_32.fp_addr,
2423 ~0, // no index provided.
2424 fib_index,
2425 1,
2426 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002427
2428 /*
2429 * -2 entries (BGP and RR). -1 shared path-list;
2430 */
Neale Ranns2303cb12018-02-21 04:57:17 -08002431 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2432 FIB_NODE_INDEX_INVALID),
2433 "200.200.200.201/32 removed");
2434 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2435 FIB_NODE_INDEX_INVALID),
2436 "1.1.1.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002437
2438 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002439 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002440 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002441 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002442 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002443 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002444
2445 /*
2446 * remove 200.200.200.200/32 which does have a valid via FIB
2447 */
2448 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002449 &bgp_200_pfx,
2450 FIB_SOURCE_API,
2451 DPO_PROTO_IP4,
2452 &pfx_1_1_1_2_s_32.fp_addr,
2453 ~0, // no index provided.
2454 fib_index,
2455 1,
2456 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002457
Neale Ranns2303cb12018-02-21 04:57:17 -08002458 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2459 FIB_NODE_INDEX_INVALID),
2460 "200.200.200.200/32 removed");
2461 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2462 FIB_NODE_INDEX_INVALID),
2463 "1.1.1.2/32 still present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002464
2465 /*
2466 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2467 */
2468 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002469 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002470 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002471 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002472 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002473 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002474
2475 /*
2476 * A recursive prefix that has a 2 path load-balance.
2477 * It also shares a next-hop with other BGP prefixes and hence
2478 * test the ref counting of RR sourced prefixes and 2 level LB.
2479 */
2480 const fib_prefix_t bgp_102 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002481 .fp_len = 32,
2482 .fp_proto = FIB_PROTOCOL_IP4,
2483 .fp_addr = {
2484 /* 100.100.100.101/32 */
2485 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2486 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002487 };
2488 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002489 &bgp_102,
2490 FIB_SOURCE_API,
2491 FIB_ENTRY_FLAG_NONE,
2492 DPO_PROTO_IP4,
2493 &pfx_1_1_1_1_s_32.fp_addr,
2494 ~0, // no index provided.
2495 fib_index, // same as route
2496 1,
2497 NULL,
2498 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002499 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002500 &bgp_102,
2501 FIB_SOURCE_API,
2502 FIB_ENTRY_FLAG_NONE,
2503 DPO_PROTO_IP4,
2504 &pfx_1_1_1_2_s_32.fp_addr,
2505 ~0, // no index provided.
2506 fib_index, // same as route's FIB
2507 1,
2508 NULL,
2509 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002510 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2511 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2512 dpo = fib_entry_contribute_ip_forwarding(fei);
2513
2514 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2515 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2516 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2517 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2518
2519 lb = load_balance_get(dpo->dpoi_index);
2520 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2521 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002522 "First via 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002523 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002524 "Second via 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002525
2526 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002527 &bgp_102,
2528 FIB_SOURCE_API,
2529 DPO_PROTO_IP4,
2530 &pfx_1_1_1_1_s_32.fp_addr,
2531 ~0, // no index provided.
2532 fib_index, // same as route's FIB
2533 1,
2534 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002535 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002536 &bgp_102,
2537 FIB_SOURCE_API,
2538 DPO_PROTO_IP4,
2539 &pfx_1_1_1_2_s_32.fp_addr,
2540 ~0, // no index provided.
2541 fib_index, // same as route's FIB
2542 1,
2543 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002544 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2545 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2546
2547 /*
2548 * remove the remaining recursives
2549 */
2550 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002551 &bgp_100_pfx,
2552 FIB_SOURCE_API,
2553 DPO_PROTO_IP4,
2554 &pfx_1_1_1_1_s_32.fp_addr,
2555 ~0, // no index provided.
2556 fib_index, // same as route's FIB
2557 1,
2558 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002559 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002560 &bgp_101_pfx,
2561 FIB_SOURCE_API,
2562 DPO_PROTO_IP4,
2563 &pfx_1_1_1_1_s_32.fp_addr,
2564 ~0, // no index provided.
2565 fib_index, // same as route's FIB
2566 1,
2567 FIB_ROUTE_PATH_FLAG_NONE);
2568 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2569 FIB_NODE_INDEX_INVALID),
2570 "100.100.100.100/32 removed");
2571 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2572 FIB_NODE_INDEX_INVALID),
2573 "100.100.100.101/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002574
2575 /*
2576 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2577 */
2578 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002579 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002580 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002581 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002582 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002583 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002584
2585 /*
2586 * Add a recursive route via a connected cover, using an adj-fib that does exist
2587 */
2588 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002589 &bgp_200_pfx,
2590 FIB_SOURCE_API,
2591 FIB_ENTRY_FLAG_NONE,
2592 DPO_PROTO_IP4,
2593 &nh_10_10_10_1,
2594 ~0, // no index provided.
2595 fib_index, // Same as route's FIB
2596 1,
2597 NULL,
2598 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002599
2600 /*
2601 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2602 */
2603 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002604 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002605 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002606 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002607 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002608 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002609
2610 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2611 dpo = fib_entry_contribute_ip_forwarding(fei);
2612
2613 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2614 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2615
2616 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002617 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002618
2619 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002620 "Flags set on RR via existing attached");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002621
2622 /*
2623 * Add a recursive route via a connected cover, using and adj-fib that does
2624 * not exist
2625 */
2626 ip46_address_t nh_10_10_10_3 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002627 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002628 };
2629 fib_prefix_t pfx_10_10_10_3 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002630 .fp_len = 32,
2631 .fp_proto = FIB_PROTOCOL_IP4,
2632 .fp_addr = nh_10_10_10_3,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002633 };
2634
2635 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002636 &bgp_201_pfx,
2637 FIB_SOURCE_API,
2638 FIB_ENTRY_FLAG_NONE,
2639 DPO_PROTO_IP4,
2640 &nh_10_10_10_3,
2641 ~0, // no index provided.
2642 fib_index,
2643 1,
2644 NULL,
2645 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002646
2647 /*
2648 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2649 * one unshared non-recursive via 10.10.10.3
2650 */
2651 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002652 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002653 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002654 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002655 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002656 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002657
2658 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08002659 VNET_LINK_IP4,
2660 &nh_10_10_10_3,
2661 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002662
2663 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2664 dpo = fib_entry_contribute_ip_forwarding(fei);
2665 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2666 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2667
2668 ai = fib_entry_get_adj(fei);
2669 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2670 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002671 fib_entry_get_flags(fei)),
2672 "Flags set on RR via non-existing attached");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002673
2674 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002675 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002676
2677 adj_unlock(ai_03);
2678
2679 /*
2680 * remove the recursives
2681 */
2682 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002683 &bgp_200_pfx,
2684 FIB_SOURCE_API,
2685 DPO_PROTO_IP4,
2686 &nh_10_10_10_1,
2687 ~0, // no index provided.
2688 fib_index, // same as route's FIB
2689 1,
2690 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002691 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002692 &bgp_201_pfx,
2693 FIB_SOURCE_API,
2694 DPO_PROTO_IP4,
2695 &nh_10_10_10_3,
2696 ~0, // no index provided.
2697 fib_index, // same as route's FIB
2698 1,
2699 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002700
2701 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002702 FIB_NODE_INDEX_INVALID),
2703 "200.200.200.201/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002704 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002705 FIB_NODE_INDEX_INVALID),
2706 "200.200.200.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002707 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002708 FIB_NODE_INDEX_INVALID),
2709 "10.10.10.3/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002710
2711 /*
2712 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2713 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2714 */
2715 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002716 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002717 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002718 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002719 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002720 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002721
2722
2723 /*
2724 * RECURSION LOOPS
2725 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2726 */
2727 fib_prefix_t pfx_5_5_5_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002728 .fp_len = 32,
2729 .fp_proto = FIB_PROTOCOL_IP4,
2730 .fp_addr = {
2731 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2732 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002733 };
2734 fib_prefix_t pfx_5_5_5_6_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002735 .fp_len = 32,
2736 .fp_proto = FIB_PROTOCOL_IP4,
2737 .fp_addr = {
2738 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2739 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002740 };
2741 fib_prefix_t pfx_5_5_5_7_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002742 .fp_len = 32,
2743 .fp_proto = FIB_PROTOCOL_IP4,
2744 .fp_addr = {
2745 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2746 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002747 };
2748
2749 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002750 &pfx_5_5_5_5_s_32,
2751 FIB_SOURCE_API,
2752 FIB_ENTRY_FLAG_NONE,
2753 DPO_PROTO_IP4,
2754 &pfx_5_5_5_6_s_32.fp_addr,
2755 ~0, // no index provided.
2756 fib_index,
2757 1,
2758 NULL,
2759 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002760 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002761 &pfx_5_5_5_6_s_32,
2762 FIB_SOURCE_API,
2763 FIB_ENTRY_FLAG_NONE,
2764 DPO_PROTO_IP4,
2765 &pfx_5_5_5_7_s_32.fp_addr,
2766 ~0, // no index provided.
2767 fib_index,
2768 1,
2769 NULL,
2770 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002771 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002772 &pfx_5_5_5_7_s_32,
2773 FIB_SOURCE_API,
2774 FIB_ENTRY_FLAG_NONE,
2775 DPO_PROTO_IP4,
2776 &pfx_5_5_5_5_s_32.fp_addr,
2777 ~0, // no index provided.
2778 fib_index,
2779 1,
2780 NULL,
2781 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002782 /*
2783 * +3 entries, +3 shared path-list
2784 */
2785 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002786 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002787 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002788 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002789 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002790 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002791
2792 /*
2793 * All the entries have only looped paths, so they are all drop
2794 */
2795 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2796 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002797 "LB for 5.5.5.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002798 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2799 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002800 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002801 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2802 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002803 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002804
2805 /*
2806 * provide 5.5.5.6/32 with alternate path.
2807 * this will allow only 5.5.5.6/32 to forward with this path, the others
2808 * are still drop since the loop is still present.
2809 */
2810 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002811 &pfx_5_5_5_6_s_32,
2812 FIB_SOURCE_API,
2813 FIB_ENTRY_FLAG_NONE,
2814 DPO_PROTO_IP4,
2815 &nh_10_10_10_1,
2816 tm->hw[0]->sw_if_index,
2817 ~0,
2818 1,
2819 NULL,
2820 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002821
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002822 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2823 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2824
2825 lb = load_balance_get(dpo1->dpoi_index);
2826 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2827
2828 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2829 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2830 FIB_TEST((ai_01 == dpo2->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002831 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002832
2833 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2834 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002835 "LB for 5.5.5.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002836 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2837 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002838 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002839
2840 /*
2841 * remove the alternate path for 5.5.5.6/32
2842 * back to all drop
2843 */
2844 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002845 &pfx_5_5_5_6_s_32,
2846 FIB_SOURCE_API,
2847 DPO_PROTO_IP4,
2848 &nh_10_10_10_1,
2849 tm->hw[0]->sw_if_index,
2850 ~0,
2851 1,
2852 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002853
2854 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2855 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002856 "LB for 5.5.5.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002857 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2858 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002859 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002860 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2861 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002862 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002863
2864 /*
2865 * break the loop by giving 5.5.5.5/32 a new set of paths
2866 * expect all to forward via this new path.
2867 */
2868 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002869 &pfx_5_5_5_5_s_32,
2870 FIB_SOURCE_API,
2871 FIB_ENTRY_FLAG_NONE,
2872 DPO_PROTO_IP4,
2873 &nh_10_10_10_1,
2874 tm->hw[0]->sw_if_index,
2875 ~0, // invalid fib index
2876 1,
2877 NULL,
2878 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002879
2880 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2881 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2882 lb = load_balance_get(dpo1->dpoi_index);
2883 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2884
2885 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2886 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2887 FIB_TEST((ai_01 == dpo2->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002888 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002889
2890 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2891 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2892
2893 lb = load_balance_get(dpo2->dpoi_index);
2894 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2895 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002896 "5.5.5.5.7 via 5.5.5.5");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002897
2898 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2899 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2900
2901 lb = load_balance_get(dpo1->dpoi_index);
2902 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2903 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002904 "5.5.5.5.6 via 5.5.5.7");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002905
2906 /*
2907 * revert back to the loop. so we can remove the prefixes with
2908 * the loop intact
2909 */
2910 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002911 &pfx_5_5_5_5_s_32,
2912 FIB_SOURCE_API,
2913 FIB_ENTRY_FLAG_NONE,
2914 DPO_PROTO_IP4,
2915 &pfx_5_5_5_6_s_32.fp_addr,
2916 ~0, // no index provided.
2917 fib_index,
2918 1,
2919 NULL,
2920 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002921
2922 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2923 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002924 "LB for 5.5.5.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002925 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2926 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002927 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002928 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2929 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002930 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002931
2932 /*
2933 * remove all the 5.5.5.x/32 prefixes
2934 */
2935 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002936 &pfx_5_5_5_5_s_32,
2937 FIB_SOURCE_API,
2938 DPO_PROTO_IP4,
2939 &pfx_5_5_5_6_s_32.fp_addr,
2940 ~0, // no index provided.
2941 fib_index, // same as route's FIB
2942 1,
2943 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002944 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002945 &pfx_5_5_5_6_s_32,
2946 FIB_SOURCE_API,
2947 DPO_PROTO_IP4,
2948 &pfx_5_5_5_7_s_32.fp_addr,
2949 ~0, // no index provided.
2950 fib_index, // same as route's FIB
2951 1,
2952 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002953 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002954 &pfx_5_5_5_7_s_32,
2955 FIB_SOURCE_API,
2956 DPO_PROTO_IP4,
2957 &pfx_5_5_5_5_s_32.fp_addr,
2958 ~0, // no index provided.
2959 fib_index, // same as route's FIB
2960 1,
2961 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002962 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002963 &pfx_5_5_5_6_s_32,
2964 FIB_SOURCE_API,
2965 DPO_PROTO_IP4,
2966 &nh_10_10_10_2,
2967 ~0, // no index provided.
2968 fib_index, // same as route's FIB
2969 1,
2970 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002971
2972 /*
2973 * -3 entries, -3 shared path-list
2974 */
2975 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002976 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002977 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002978 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002979 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002980 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002981
2982 /*
2983 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2984 */
2985 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002986 &pfx_5_5_5_6_s_32,
2987 FIB_SOURCE_API,
2988 FIB_ENTRY_FLAG_NONE,
2989 DPO_PROTO_IP4,
2990 &pfx_5_5_5_6_s_32.fp_addr,
2991 ~0, // no index provided.
2992 fib_index,
2993 1,
2994 NULL,
2995 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002996 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2997 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002998 "1-level 5.5.5.6/32 loop is via adj for DROP");
2999
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003000 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003001 &pfx_5_5_5_6_s_32,
3002 FIB_SOURCE_API,
3003 DPO_PROTO_IP4,
3004 &pfx_5_5_5_6_s_32.fp_addr,
3005 ~0, // no index provided.
3006 fib_index, // same as route's FIB
3007 1,
3008 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003009 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003010 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
3011 "1-level 5.5.5.6/32 loop is removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003012
3013 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003014 * A recursive route whose next-hop is covered by the prefix.
3015 * This would mean the via-fib, which inherits forwarding from its
3016 * cover, thus picks up forwarding from the prfix, which is via the
3017 * via-fib, and we have a loop.
3018 */
3019 fib_prefix_t pfx_23_23_23_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003020 .fp_len = 24,
3021 .fp_proto = FIB_PROTOCOL_IP4,
3022 .fp_addr = {
3023 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
3024 },
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003025 };
3026 fib_prefix_t pfx_23_23_23_23_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003027 .fp_len = 32,
3028 .fp_proto = FIB_PROTOCOL_IP4,
3029 .fp_addr = {
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003030 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
3031 },
3032 };
3033 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003034 &pfx_23_23_23_0_s_24,
3035 FIB_SOURCE_API,
3036 FIB_ENTRY_FLAG_NONE,
3037 DPO_PROTO_IP4,
3038 &pfx_23_23_23_23_s_32.fp_addr,
3039 ~0, // recursive
3040 fib_index,
3041 1,
3042 NULL,
3043 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003044 dpo = fib_entry_contribute_ip_forwarding(fei);
3045 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003046 "23.23.23.0/24 via covered is DROP");
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003047 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3048
3049 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003050 * add-remove test. no change.
3051 */
3052 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003053 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003054 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003055 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003056 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003057 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003058
3059 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003060 * Make the default route recursive via a unknown next-hop. Thus the
3061 * next hop's cover would be the default route
3062 */
3063 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003064 &pfx_0_0_0_0_s_0,
3065 FIB_SOURCE_API,
3066 FIB_ENTRY_FLAG_NONE,
3067 DPO_PROTO_IP4,
3068 &pfx_23_23_23_23_s_32.fp_addr,
3069 ~0, // recursive
3070 fib_index,
3071 1,
3072 NULL,
3073 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns08b16482017-05-13 05:52:58 -07003074 dpo = fib_entry_contribute_ip_forwarding(fei);
3075 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003076 "0.0.0.0.0/0 via is DROP");
Neale Ranns08b16482017-05-13 05:52:58 -07003077 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3078 "no resolving interface for looped 0.0.0.0/0");
3079
3080 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3081 dpo = fib_entry_contribute_ip_forwarding(fei);
3082 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003083 "23.23.23.23/32 via is DROP");
Neale Ranns08b16482017-05-13 05:52:58 -07003084 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3085 "no resolving interface for looped 23.23.23.23/32");
3086
3087 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3088
3089 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003090 * A recursive route with recursion constraints.
3091 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3092 */
3093 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003094 &bgp_200_pfx,
3095 FIB_SOURCE_API,
3096 FIB_ENTRY_FLAG_NONE,
3097 DPO_PROTO_IP4,
3098 &nh_1_1_1_1,
3099 ~0,
3100 fib_index,
3101 1,
3102 NULL,
3103 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003104
3105 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3106 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3107
3108 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3109 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3110
3111 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003112 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003113
3114 /*
3115 * save the load-balance. we expect it to be inplace modified
3116 */
3117 lb = load_balance_get(dpo1->dpoi_index);
3118
3119 /*
3120 * add a covering prefix for the via fib that would otherwise serve
3121 * as the resolving route when the host is removed
3122 */
3123 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003124 &pfx_1_1_1_0_s_28,
3125 FIB_SOURCE_API,
3126 FIB_ENTRY_FLAG_NONE,
3127 DPO_PROTO_IP4,
3128 &nh_10_10_10_1,
3129 tm->hw[0]->sw_if_index,
3130 ~0, // invalid fib index
3131 1,
3132 NULL,
3133 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003134 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3135 ai = fib_entry_get_adj(fei);
3136 FIB_TEST((ai == ai_01),
Neale Ranns2303cb12018-02-21 04:57:17 -08003137 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003138
3139 /*
3140 * remove the host via FIB - expect the BGP prefix to be drop
3141 */
3142 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003143 &pfx_1_1_1_1_s_32,
3144 FIB_SOURCE_API,
3145 DPO_PROTO_IP4,
3146 &nh_10_10_10_1,
3147 tm->hw[0]->sw_if_index,
3148 ~0, // invalid fib index
3149 1,
3150 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003151
3152 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003153 "adj for 200.200.200.200/32 is recursive via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003154
3155 /*
3156 * add the via-entry host reoute back. expect to resolve again
3157 */
3158 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003159 &pfx_1_1_1_1_s_32,
3160 FIB_SOURCE_API,
3161 FIB_ENTRY_FLAG_NONE,
3162 DPO_PROTO_IP4,
3163 &nh_10_10_10_1,
3164 tm->hw[0]->sw_if_index,
3165 ~0, // invalid fib index
3166 1,
3167 NULL,
3168 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003169 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003170 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003171
3172 /*
3173 * add another path for the recursive. it will then have 2.
3174 */
3175 fib_prefix_t pfx_1_1_1_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003176 .fp_len = 32,
3177 .fp_proto = FIB_PROTOCOL_IP4,
3178 .fp_addr = {
3179 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3180 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003181 };
3182 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003183 &pfx_1_1_1_3_s_32,
3184 FIB_SOURCE_API,
3185 FIB_ENTRY_FLAG_NONE,
3186 DPO_PROTO_IP4,
3187 &nh_10_10_10_2,
3188 tm->hw[0]->sw_if_index,
3189 ~0, // invalid fib index
3190 1,
3191 NULL,
3192 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003193
3194 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003195 &bgp_200_pfx,
3196 FIB_SOURCE_API,
3197 FIB_ENTRY_FLAG_NONE,
3198 DPO_PROTO_IP4,
3199 &pfx_1_1_1_3_s_32.fp_addr,
3200 ~0,
3201 fib_index,
3202 1,
3203 NULL,
3204 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003205
Neale Rannsf12a83f2017-04-18 09:09:40 -07003206 /*
3207 * add a bunch load more entries using this path combo so that we get
3208 * an LB-map created.
3209 */
3210#define N_P 128
3211 fib_prefix_t bgp_78s[N_P];
3212 for (ii = 0; ii < N_P; ii++)
3213 {
3214 bgp_78s[ii].fp_len = 32;
3215 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3216 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3217
Neale Ranns2303cb12018-02-21 04:57:17 -08003218
Neale Rannsf12a83f2017-04-18 09:09:40 -07003219 fib_table_entry_path_add(fib_index,
3220 &bgp_78s[ii],
3221 FIB_SOURCE_API,
3222 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003223 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003224 &pfx_1_1_1_3_s_32.fp_addr,
3225 ~0,
3226 fib_index,
3227 1,
3228 NULL,
3229 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3230 fib_table_entry_path_add(fib_index,
3231 &bgp_78s[ii],
3232 FIB_SOURCE_API,
3233 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003234 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003235 &nh_1_1_1_1,
3236 ~0,
3237 fib_index,
3238 1,
3239 NULL,
3240 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3241 }
3242
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003243 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3244 dpo = fib_entry_contribute_ip_forwarding(fei);
3245
3246 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3247 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3248 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003249 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003250 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3251 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3252 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003253 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003254
3255 /*
3256 * expect the lb-map used by the recursive's load-balance is using both buckets
3257 */
3258 load_balance_map_t *lbm;
3259 index_t lbmi;
3260
3261 lb = load_balance_get(dpo->dpoi_index);
3262 lbmi = lb->lb_map;
3263 load_balance_map_lock(lbmi);
3264 lbm = load_balance_map_get(lbmi);
3265
3266 FIB_TEST(lbm->lbm_buckets[0] == 0,
3267 "LB maps's bucket 0 is %d",
3268 lbm->lbm_buckets[0]);
3269 FIB_TEST(lbm->lbm_buckets[1] == 1,
3270 "LB maps's bucket 1 is %d",
3271 lbm->lbm_buckets[1]);
3272
3273 /*
3274 * withdraw one of the /32 via-entrys.
3275 * that ECMP path will be unresolved and forwarding should continue on the
3276 * other available path. this is an iBGP PIC edge failover.
3277 * Test the forwarding changes without re-fetching the adj from the
3278 * recursive entry. this ensures its the same one that is updated; i.e. an
3279 * inplace-modify.
3280 */
3281 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003282 &pfx_1_1_1_1_s_32,
3283 FIB_SOURCE_API,
3284 DPO_PROTO_IP4,
3285 &nh_10_10_10_1,
3286 tm->hw[0]->sw_if_index,
3287 ~0, // invalid fib index
3288 1,
3289 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003290
Neale Rannsf12a83f2017-04-18 09:09:40 -07003291 /* suspend so the update walk kicks int */
3292 vlib_process_suspend(vlib_get_main(), 1e-5);
3293
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003294 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3295 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003296 "post PIC 200.200.200.200/32 was inplace modified");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003297
3298 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003299 "post PIC adj for 200.200.200.200/32 is recursive"
3300 " via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003301
3302 /*
3303 * the LB maps that was locked above should have been modified to remove
3304 * the path that was down, and thus its bucket points to a path that is
3305 * still up.
3306 */
3307 FIB_TEST(lbm->lbm_buckets[0] == 1,
3308 "LB maps's bucket 0 is %d",
3309 lbm->lbm_buckets[0]);
3310 FIB_TEST(lbm->lbm_buckets[1] == 1,
3311 "LB maps's bucket 1 is %d",
3312 lbm->lbm_buckets[1]);
3313
Neale Ranns994dab42017-04-18 12:56:45 -07003314 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003315
3316 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08003317 * add it back. again
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003318 */
3319 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003320 &pfx_1_1_1_1_s_32,
3321 FIB_SOURCE_API,
3322 FIB_ENTRY_FLAG_NONE,
3323 DPO_PROTO_IP4,
3324 &nh_10_10_10_1,
3325 tm->hw[0]->sw_if_index,
3326 ~0, // invalid fib index
3327 1,
3328 NULL,
3329 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003330
Neale Rannsf12a83f2017-04-18 09:09:40 -07003331 /* suspend so the update walk kicks in */
3332 vlib_process_suspend(vlib_get_main(), 1e-5);
3333
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003334 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003335 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3336 "via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003337 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003338 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3339 "via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003340
3341 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3342 dpo = fib_entry_contribute_ip_forwarding(fei);
3343 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003344 "post PIC 200.200.200.200/32 was inplace modified");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003345
3346 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08003347 * add a 3rd path. this makes the LB 16 buckets.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003348 */
3349 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003350 &bgp_200_pfx,
3351 FIB_SOURCE_API,
3352 FIB_ENTRY_FLAG_NONE,
3353 DPO_PROTO_IP4,
3354 &pfx_1_1_1_2_s_32.fp_addr,
3355 ~0,
3356 fib_index,
3357 1,
3358 NULL,
3359 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003360 for (ii = 0; ii < N_P; ii++)
3361 {
3362 fib_table_entry_path_add(fib_index,
3363 &bgp_78s[ii],
Neale Ranns2303cb12018-02-21 04:57:17 -08003364 FIB_SOURCE_API,
3365 FIB_ENTRY_FLAG_NONE,
3366 DPO_PROTO_IP4,
3367 &pfx_1_1_1_2_s_32.fp_addr,
3368 ~0,
3369 fib_index,
3370 1,
3371 NULL,
3372 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003373 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003374
3375 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3376 dpo = fib_entry_contribute_ip_forwarding(fei);
3377 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003378 "200.200.200.200/32 was inplace modified for 3rd path");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003379 FIB_TEST(16 == lb->lb_n_buckets,
Neale Ranns2303cb12018-02-21 04:57:17 -08003380 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003381
3382 lbmi = lb->lb_map;
3383 load_balance_map_lock(lbmi);
3384 lbm = load_balance_map_get(lbmi);
3385
3386 for (ii = 0; ii < 16; ii++)
3387 {
3388 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3389 "LB Map for 200.200.200.200/32 at %d is %d",
3390 ii, lbm->lbm_buckets[ii]);
3391 }
3392
3393 /*
3394 * trigger PIC by removing the first via-entry
3395 * the first 6 buckets of the map should map to the next 6
3396 */
3397 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003398 &pfx_1_1_1_1_s_32,
3399 FIB_SOURCE_API,
3400 DPO_PROTO_IP4,
3401 &nh_10_10_10_1,
3402 tm->hw[0]->sw_if_index,
3403 ~0,
3404 1,
3405 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003406 /* suspend so the update walk kicks int */
3407 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003408
3409 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3410 dpo = fib_entry_contribute_ip_forwarding(fei);
3411 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003412 "200.200.200.200/32 was inplace modified for 3rd path");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003413 FIB_TEST(2 == lb->lb_n_buckets,
Neale Ranns2303cb12018-02-21 04:57:17 -08003414 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003415
3416 for (ii = 0; ii < 6; ii++)
3417 {
3418 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3419 "LB Map for 200.200.200.200/32 at %d is %d",
3420 ii, lbm->lbm_buckets[ii]);
3421 }
3422 for (ii = 6; ii < 16; ii++)
3423 {
3424 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3425 "LB Map for 200.200.200.200/32 at %d is %d",
3426 ii, lbm->lbm_buckets[ii]);
3427 }
Neale Ranns994dab42017-04-18 12:56:45 -07003428 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003429
3430 /*
3431 * tidy up
3432 */
3433 fib_table_entry_path_add(fib_index,
3434 &pfx_1_1_1_1_s_32,
3435 FIB_SOURCE_API,
3436 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08003437 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003438 &nh_10_10_10_1,
3439 tm->hw[0]->sw_if_index,
3440 ~0,
3441 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003442 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003443 FIB_ROUTE_PATH_FLAG_NONE);
3444
Neale Rannsf12a83f2017-04-18 09:09:40 -07003445 for (ii = 0; ii < N_P; ii++)
3446 {
3447 fib_table_entry_delete(fib_index,
3448 &bgp_78s[ii],
3449 FIB_SOURCE_API);
3450 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3451 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3452 "%U removed",
3453 format_fib_prefix, &bgp_78s[ii]);
3454 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003455 fib_table_entry_path_remove(fib_index,
3456 &bgp_200_pfx,
3457 FIB_SOURCE_API,
Neale Ranns2303cb12018-02-21 04:57:17 -08003458 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003459 &pfx_1_1_1_2_s_32.fp_addr,
3460 ~0,
3461 fib_index,
3462 1,
3463 MPLS_LABEL_INVALID);
3464 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003465 &bgp_200_pfx,
3466 FIB_SOURCE_API,
3467 DPO_PROTO_IP4,
3468 &nh_1_1_1_1,
3469 ~0,
3470 fib_index,
3471 1,
3472 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003473 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003474 &bgp_200_pfx,
3475 FIB_SOURCE_API,
3476 DPO_PROTO_IP4,
3477 &pfx_1_1_1_3_s_32.fp_addr,
3478 ~0,
3479 fib_index,
3480 1,
3481 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003482 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003483 &pfx_1_1_1_3_s_32,
3484 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003485 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003486 &pfx_1_1_1_0_s_28,
3487 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003488 /* suspend so the update walk kicks int */
3489 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003490 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003491 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28)),
3492 "1.1.1.1/28 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003493 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003494 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32)),
3495 "1.1.1.3/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003496 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003497 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3498 "200.200.200.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003499
3500 /*
3501 * add-remove test. no change.
3502 */
3503 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003504 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003505 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003506 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003507 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003508 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003509
3510 /*
3511 * A route whose paths are built up iteratively and then removed
3512 * all at once
3513 */
3514 fib_prefix_t pfx_4_4_4_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003515 .fp_len = 32,
3516 .fp_proto = FIB_PROTOCOL_IP4,
3517 .fp_addr = {
3518 /* 4.4.4.4/32 */
3519 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3520 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003521 };
3522
3523 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003524 &pfx_4_4_4_4_s_32,
3525 FIB_SOURCE_API,
3526 FIB_ENTRY_FLAG_NONE,
3527 DPO_PROTO_IP4,
3528 &nh_10_10_10_1,
3529 tm->hw[0]->sw_if_index,
3530 ~0,
3531 1,
3532 NULL,
3533 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003534 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003535 &pfx_4_4_4_4_s_32,
3536 FIB_SOURCE_API,
3537 FIB_ENTRY_FLAG_NONE,
3538 DPO_PROTO_IP4,
3539 &nh_10_10_10_2,
3540 tm->hw[0]->sw_if_index,
3541 ~0,
3542 1,
3543 NULL,
3544 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003545 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003546 &pfx_4_4_4_4_s_32,
3547 FIB_SOURCE_API,
3548 FIB_ENTRY_FLAG_NONE,
3549 DPO_PROTO_IP4,
3550 &nh_10_10_10_3,
3551 tm->hw[0]->sw_if_index,
3552 ~0,
3553 1,
3554 NULL,
3555 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003556 FIB_TEST(FIB_NODE_INDEX_INVALID !=
Neale Ranns2303cb12018-02-21 04:57:17 -08003557 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3558 "4.4.4.4/32 present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003559
3560 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003561 &pfx_4_4_4_4_s_32,
3562 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003563 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003564 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3565 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003566
3567 /*
3568 * add-remove test. no change.
3569 */
3570 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003571 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003572 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003573 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003574 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003575 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003576
3577 /*
3578 * A route with multiple paths at once
3579 */
3580 fib_route_path_t *r_paths = NULL;
3581
3582 for (ii = 0; ii < 4; ii++)
3583 {
Neale Ranns2303cb12018-02-21 04:57:17 -08003584 fib_route_path_t r_path = {
3585 .frp_proto = DPO_PROTO_IP4,
3586 .frp_addr = {
3587 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3588 },
3589 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3590 .frp_weight = 1,
3591 .frp_fib_index = ~0,
3592 };
3593 vec_add1(r_paths, r_path);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003594 }
3595
3596 fib_table_entry_update(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003597 &pfx_4_4_4_4_s_32,
3598 FIB_SOURCE_API,
3599 FIB_ENTRY_FLAG_NONE,
3600 r_paths);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003601
3602 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3603 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3604 dpo = fib_entry_contribute_ip_forwarding(fei);
3605
3606 lb = load_balance_get(dpo->dpoi_index);
3607 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3608
3609 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003610 &pfx_4_4_4_4_s_32,
3611 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003612 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003613 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3614 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003615 vec_free(r_paths);
3616
3617 /*
3618 * add-remove test. no change.
3619 */
3620 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003621 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003622 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003623 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003624 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003625 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003626
3627 /*
3628 * A route deag route
3629 */
3630 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003631 &pfx_4_4_4_4_s_32,
3632 FIB_SOURCE_API,
3633 FIB_ENTRY_FLAG_NONE,
3634 DPO_PROTO_IP4,
3635 &zero_addr,
3636 ~0,
3637 fib_index,
3638 1,
3639 NULL,
3640 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003641
3642 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3643 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3644
3645 dpo = fib_entry_contribute_ip_forwarding(fei);
3646 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3647 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3648
3649 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003650 "4.4.4.4/32 is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003651 lkd->lkd_fib_index,
3652 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003653 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
Neale Ranns2303cb12018-02-21 04:57:17 -08003654 "4.4.4.4/32 is source deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003655 lkd->lkd_input,
3656 format_dpo_id, dpo, 0);
3657
3658 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003659 &pfx_4_4_4_4_s_32,
3660 FIB_SOURCE_API);
Neale Ranns054c03a2017-10-13 05:15:07 -07003661 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003662 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3663 "4.4.4.4/32 removed");
Neale Ranns054c03a2017-10-13 05:15:07 -07003664 vec_free(r_paths);
3665
3666 /*
3667 * A route deag route in a source lookup table
3668 */
3669 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003670 &pfx_4_4_4_4_s_32,
3671 FIB_SOURCE_API,
3672 FIB_ENTRY_FLAG_NONE,
3673 DPO_PROTO_IP4,
3674 &zero_addr,
3675 ~0,
3676 fib_index,
3677 1,
3678 NULL,
3679 FIB_ROUTE_PATH_SOURCE_LOOKUP);
Neale Ranns054c03a2017-10-13 05:15:07 -07003680
3681 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3682 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3683
3684 dpo = fib_entry_contribute_ip_forwarding(fei);
3685 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3686 lkd = lookup_dpo_get(dpo->dpoi_index);
3687
3688 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003689 "4.4.4.4/32 is deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003690 lkd->lkd_fib_index,
3691 format_dpo_id, dpo, 0);
3692 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
Neale Ranns2303cb12018-02-21 04:57:17 -08003693 "4.4.4.4/32 is source deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003694 lkd->lkd_input,
3695 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003696
3697 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003698 &pfx_4_4_4_4_s_32,
3699 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003700 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003701 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3702 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003703 vec_free(r_paths);
3704
3705 /*
3706 * add-remove test. no change.
3707 */
3708 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003709 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003710 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003711 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003712 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003713 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003714
3715 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003716 * Duplicate paths:
3717 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3718 */
3719 fib_prefix_t pfx_34_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003720 .fp_len = 32,
3721 .fp_proto = FIB_PROTOCOL_IP4,
3722 .fp_addr = {
3723 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3724 },
Neale Rannsbcc889c2016-11-03 14:15:28 -07003725 };
3726 fib_prefix_t pfx_34_34_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003727 .fp_len = 32,
3728 .fp_proto = FIB_PROTOCOL_IP4,
3729 .fp_addr = {
3730 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3731 },
Neale Rannsbcc889c2016-11-03 14:15:28 -07003732 };
3733 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003734 &pfx_34_34_1_1_s_32,
3735 FIB_SOURCE_API,
3736 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003737 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003738 &nh_10_10_10_1,
3739 tm->hw[0]->sw_if_index,
3740 0,
3741 1,
3742 NULL,
3743 FIB_ROUTE_PATH_FLAG_NONE);
3744 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003745 &pfx_34_1_1_1_s_32,
3746 FIB_SOURCE_API,
3747 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003748 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003749 &pfx_34_34_1_1_s_32.fp_addr,
3750 ~0,
3751 fib_index,
3752 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003753 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003754 FIB_ROUTE_PATH_FLAG_NONE);
3755 fei = fib_table_entry_path_add(fib_index,
3756 &pfx_34_1_1_1_s_32,
3757 FIB_SOURCE_API,
3758 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003759 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003760 &pfx_34_34_1_1_s_32.fp_addr,
3761 ~0,
3762 fib_index,
3763 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003764 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003765 FIB_ROUTE_PATH_FLAG_NONE);
3766 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3767 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003768 fib_table_entry_delete(fib_index,
3769 &pfx_34_34_1_1_s_32,
3770 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003771
3772 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003773 * CLEANUP
3774 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3775 * all of which are via 10.10.10.1, Itf1
3776 */
3777 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003778 &pfx_1_1_1_2_s_32,
3779 FIB_SOURCE_API,
3780 DPO_PROTO_IP4,
3781 &nh_10_10_10_1,
3782 tm->hw[0]->sw_if_index,
3783 ~0,
3784 1,
3785 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003786 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003787 &pfx_1_1_1_1_s_32,
3788 FIB_SOURCE_API,
3789 DPO_PROTO_IP4,
3790 &nh_10_10_10_1,
3791 tm->hw[0]->sw_if_index,
3792 ~0,
3793 1,
3794 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003795 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003796 &pfx_1_1_2_0_s_24,
3797 FIB_SOURCE_API,
3798 DPO_PROTO_IP4,
3799 &nh_10_10_10_1,
3800 tm->hw[0]->sw_if_index,
3801 ~0,
3802 1,
3803 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003804
3805 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003806 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32),
3807 "1.1.1.1/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003808 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003809 fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32),
3810 "1.1.1.2/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003811 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003812 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3813 "1.1.2.0/24 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003814
3815 /*
3816 * -3 entries and -1 shared path-list
3817 */
3818 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003819 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003820 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003821 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003822 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003823 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003824
3825 /*
3826 * An attached-host route. Expect to link to the incomplete adj
3827 */
3828 fib_prefix_t pfx_4_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003829 .fp_len = 32,
3830 .fp_proto = FIB_PROTOCOL_IP4,
3831 .fp_addr = {
3832 /* 4.1.1.1/32 */
3833 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3834 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003835 };
3836 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003837 &pfx_4_1_1_1_s_32,
3838 FIB_SOURCE_API,
3839 FIB_ENTRY_FLAG_NONE,
3840 DPO_PROTO_IP4,
3841 &zero_addr,
3842 tm->hw[0]->sw_if_index,
3843 fib_index,
3844 1,
3845 NULL,
3846 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003847
3848 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3849 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3850 ai = fib_entry_get_adj(fei);
3851
3852 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08003853 VNET_LINK_IP4,
3854 &pfx_4_1_1_1_s_32.fp_addr,
3855 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003856 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3857 adj_unlock(ai2);
3858
3859 /*
3860 * +1 entry and +1 shared path-list
3861 */
3862 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003863 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003864 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003865 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003866 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003867 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003868
3869 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003870 &pfx_4_1_1_1_s_32,
3871 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003872
3873 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003874 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003875 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003876 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003877 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003878 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003879
3880 /*
3881 * add a v6 prefix via v4 next-hops
3882 */
3883 fib_prefix_t pfx_2001_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003884 .fp_len = 64,
3885 .fp_proto = FIB_PROTOCOL_IP6,
3886 .fp_addr = {
3887 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3888 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003889 };
3890 fei = fib_table_entry_path_add(0, //default v6 table
Neale Ranns2303cb12018-02-21 04:57:17 -08003891 &pfx_2001_s_64,
3892 FIB_SOURCE_API,
3893 FIB_ENTRY_FLAG_NONE,
3894 DPO_PROTO_IP4,
3895 &nh_10_10_10_1,
3896 tm->hw[0]->sw_if_index,
3897 fib_index,
3898 1,
3899 NULL,
3900 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003901
3902 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3903 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3904 ai = fib_entry_get_adj(fei);
3905 adj = adj_get(ai);
3906 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
Neale Ranns2303cb12018-02-21 04:57:17 -08003907 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003908 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns2303cb12018-02-21 04:57:17 -08003909 "2001::/64 is link type v6");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003910 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
Neale Ranns2303cb12018-02-21 04:57:17 -08003911 "2001::/64 ADJ-adj is NH proto v4");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003912 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3913
Neale Ranns3ee44042016-10-03 13:05:48 +01003914 /*
3915 * add a uRPF exempt prefix:
3916 * test:
3917 * - it's forwarding is drop
3918 * - it's uRPF list is not empty
3919 * - the uRPF list for the default route (it's cover) is empty
3920 */
3921 fei = fib_table_entry_special_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003922 &pfx_4_1_1_1_s_32,
3923 FIB_SOURCE_URPF_EXEMPT,
3924 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003925 dpo = fib_entry_contribute_ip_forwarding(fei);
3926 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003927 "uRPF exempt 4.1.1.1/32 DROP");
3928 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3929 "uRPF list for exempt prefix has itf index 0");
Neale Ranns3ee44042016-10-03 13:05:48 +01003930 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
Neale Ranns2303cb12018-02-21 04:57:17 -08003931 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3932 "uRPF list for 0.0.0.0/0 empty");
Neale Ranns3ee44042016-10-03 13:05:48 +01003933
3934 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003935
3936 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003937 * An adj-fib that fails the refinement criteria - no connected cover
3938 */
3939 fib_prefix_t pfx_12_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003940 .fp_len = 32,
3941 .fp_proto = FIB_PROTOCOL_IP4,
3942 .fp_addr = {
3943 /* 12.10.10.2 */
3944 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3945 },
Neale Ranns3983ac22017-03-10 11:53:27 -08003946 };
3947
Neale Ranns81424992017-05-18 03:03:22 -07003948 fib_table_entry_path_add(fib_index,
3949 &pfx_12_10_10_2_s_32,
3950 FIB_SOURCE_ADJ,
3951 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003952 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003953 &pfx_12_10_10_2_s_32.fp_addr,
3954 tm->hw[0]->sw_if_index,
3955 ~0, // invalid fib index
3956 1,
3957 NULL,
3958 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003959
3960 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3961 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08003962 FIB_TEST(dpo_is_drop(dpo),
3963 "no connected cover adj-fib fails refinement: %U",
3964 format_dpo_id, dpo, 0);
Neale Ranns3983ac22017-03-10 11:53:27 -08003965
3966 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003967 &pfx_12_10_10_2_s_32,
3968 FIB_SOURCE_ADJ);
Neale Ranns3983ac22017-03-10 11:53:27 -08003969
3970 /*
3971 * An adj-fib that fails the refinement criteria - cover is connected
3972 * but on a different interface
3973 */
3974 fib_prefix_t pfx_10_10_10_127_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003975 .fp_len = 32,
3976 .fp_proto = FIB_PROTOCOL_IP4,
3977 .fp_addr = {
3978 /* 10.10.10.127 */
3979 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3980 },
Neale Ranns3983ac22017-03-10 11:53:27 -08003981 };
3982
Neale Ranns81424992017-05-18 03:03:22 -07003983 fib_table_entry_path_add(fib_index,
3984 &pfx_10_10_10_127_s_32,
3985 FIB_SOURCE_ADJ,
3986 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003987 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003988 &pfx_10_10_10_127_s_32.fp_addr,
3989 tm->hw[1]->sw_if_index,
3990 ~0, // invalid fib index
3991 1,
3992 NULL,
3993 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003994
3995 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3996 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08003997 FIB_TEST(dpo_is_drop(dpo),
3998 "wrong interface adj-fib fails refinement");
Neale Ranns3983ac22017-03-10 11:53:27 -08003999
4000 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004001 &pfx_10_10_10_127_s_32,
4002 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07004003
4004 /*
4005 * add a second path to an adj-fib
4006 * this is a sumiluation of another ARP entry created
Neale Ranns2303cb12018-02-21 04:57:17 -08004007 * on an interface on which the connected prefix does not exist.
Neale Ranns81424992017-05-18 03:03:22 -07004008 * The second path fails refinement. Expect to forward through the
4009 * first.
4010 */
4011 fib_prefix_t pfx_10_10_10_3_s_32 = {
4012 .fp_len = 32,
4013 .fp_proto = FIB_PROTOCOL_IP4,
4014 .fp_addr = {
4015 /* 10.10.10.3 */
4016 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
4017 },
4018 };
4019
4020 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
4021 VNET_LINK_IP4,
4022 &nh_10_10_10_3,
4023 tm->hw[0]->sw_if_index);
4024
4025 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
4026 .type = FT_LB_ADJ,
4027 .adj = {
4028 .adj = ai_03,
4029 },
4030 };
4031 fei = fib_table_entry_path_add(fib_index,
4032 &pfx_10_10_10_3_s_32,
4033 FIB_SOURCE_ADJ,
4034 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004035 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004036 &nh_10_10_10_3,
4037 tm->hw[0]->sw_if_index,
4038 fib_index,
4039 1,
4040 NULL,
4041 FIB_ROUTE_PATH_FLAG_NONE);
4042 fei = fib_table_entry_path_add(fib_index,
4043 &pfx_10_10_10_3_s_32,
4044 FIB_SOURCE_ADJ,
4045 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004046 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004047 &nh_12_12_12_12,
4048 tm->hw[1]->sw_if_index,
4049 fib_index,
4050 1,
4051 NULL,
4052 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004053 FIB_TEST(!fib_test_validate_entry(fei,
4054 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4055 1,
4056 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004057 "10.10.10.3 via 10.10.10.3/Eth0 only");
4058
4059 /*
4060 * remove the path that refines the cover, should go unresolved
4061 */
4062 fib_table_entry_path_remove(fib_index,
4063 &pfx_10_10_10_3_s_32,
4064 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004065 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004066 &nh_10_10_10_3,
4067 tm->hw[0]->sw_if_index,
4068 fib_index,
4069 1,
4070 FIB_ROUTE_PATH_FLAG_NONE);
4071 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08004072 FIB_TEST(dpo_is_drop(dpo),
Neale Ranns81424992017-05-18 03:03:22 -07004073 "wrong interface adj-fib fails refinement");
4074
4075 /*
4076 * add back the path that refines the cover
4077 */
4078 fei = fib_table_entry_path_add(fib_index,
4079 &pfx_10_10_10_3_s_32,
4080 FIB_SOURCE_ADJ,
4081 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004082 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004083 &nh_10_10_10_3,
4084 tm->hw[0]->sw_if_index,
4085 fib_index,
4086 1,
4087 NULL,
4088 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004089 FIB_TEST(!fib_test_validate_entry(fei,
4090 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4091 1,
4092 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004093 "10.10.10.3 via 10.10.10.3/Eth0 only");
4094
4095 /*
4096 * remove the path that does not refine the cover
4097 */
4098 fib_table_entry_path_remove(fib_index,
4099 &pfx_10_10_10_3_s_32,
4100 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004101 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004102 &nh_12_12_12_12,
4103 tm->hw[1]->sw_if_index,
4104 fib_index,
4105 1,
4106 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004107 FIB_TEST(!fib_test_validate_entry(fei,
4108 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4109 1,
4110 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004111 "10.10.10.3 via 10.10.10.3/Eth0 only");
4112
4113 /*
4114 * remove the path that does refine, it's the last path, so
4115 * the entry should be gone
4116 */
4117 fib_table_entry_path_remove(fib_index,
4118 &pfx_10_10_10_3_s_32,
4119 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004120 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004121 &nh_10_10_10_3,
4122 tm->hw[0]->sw_if_index,
4123 fib_index,
4124 1,
4125 FIB_ROUTE_PATH_FLAG_NONE);
4126 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4127 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4128
4129 adj_unlock(ai_03);
4130
Neale Ranns227038a2017-04-21 01:07:59 -07004131 /*
4132 * change the table's flow-hash config - expect the update to propagete to
4133 * the entries' load-balance objects
4134 */
4135 flow_hash_config_t old_hash_config, new_hash_config;
4136
4137 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4138 FIB_PROTOCOL_IP4);
4139 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4140 IP_FLOW_HASH_DST_ADDR);
4141
4142 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4143 dpo = fib_entry_contribute_ip_forwarding(fei);
4144 lb = load_balance_get(dpo->dpoi_index);
4145 FIB_TEST((lb->lb_hash_config == old_hash_config),
4146 "Table and LB hash config match: %U",
4147 format_ip_flow_hash_config, lb->lb_hash_config);
4148
4149 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4150
4151 FIB_TEST((lb->lb_hash_config == new_hash_config),
4152 "Table and LB newhash config match: %U",
4153 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004154
4155 /*
Neale Rannsf068c3e2018-01-03 04:18:48 -08004156 * A route via DVR DPO
Neale Ranns6f631152017-10-03 08:20:21 -07004157 */
4158 fei = fib_table_entry_path_add(fib_index,
4159 &pfx_10_10_10_3_s_32,
4160 FIB_SOURCE_API,
4161 FIB_ENTRY_FLAG_NONE,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004162 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004163 &zero_addr,
4164 tm->hw[0]->sw_if_index,
4165 ~0,
4166 1,
4167 NULL,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004168 FIB_ROUTE_PATH_DVR);
4169 dpo_id_t dvr_dpo = DPO_INVALID;
4170 dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004171 fib_test_lb_bucket_t ip_o_l2 = {
4172 .type = FT_LB_L2,
4173 .adj = {
Neale Rannsf068c3e2018-01-03 04:18:48 -08004174 .adj = dvr_dpo.dpoi_index,
Neale Ranns6f631152017-10-03 08:20:21 -07004175 },
4176 };
4177
Neale Ranns2303cb12018-02-21 04:57:17 -08004178 FIB_TEST(!fib_test_validate_entry(fei,
4179 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4180 1,
4181 &ip_o_l2),
Neale Ranns6f631152017-10-03 08:20:21 -07004182 "10.10.10.3 via L2 on Eth0");
4183 fib_table_entry_path_remove(fib_index,
4184 &pfx_10_10_10_3_s_32,
4185 FIB_SOURCE_API,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004186 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004187 &zero_addr,
4188 tm->hw[0]->sw_if_index,
4189 fib_index,
4190 1,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004191 FIB_ROUTE_PATH_DVR);
4192 dpo_reset(&dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004193
4194 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004195 * CLEANUP
Neale Ranns2303cb12018-02-21 04:57:17 -08004196 * remove adj-fibs:
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004197 */
4198 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004199 &pfx_10_10_10_1_s_32,
4200 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004201 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004202 &pfx_10_10_10_2_s_32,
4203 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004204 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004205 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32),
4206 "10.10.10.1/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004207 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004208 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4209 "10.10.10.2/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004210
4211 /*
4212 * -2 entries and -2 non-shared path-list
4213 */
4214 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004215 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004216 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004217 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004218 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004219 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004220
4221 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004222 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004223 * These are the last locks on these adjs. they should thus go away.
4224 */
4225 adj_unlock(ai_02);
4226 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004227 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004228
4229 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004230 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004231
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004232 /*
4233 * CLEANUP
4234 * remove the interface prefixes
4235 */
4236 local_pfx.fp_len = 32;
4237 fib_table_entry_special_remove(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004238 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004239 fei = fib_table_lookup(fib_index, &local_pfx);
4240
4241 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004242 fib_table_lookup_exact_match(fib_index, &local_pfx),
4243 "10.10.10.10/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004244
4245 local_pfx.fp_len = 24;
4246 fib_table_entry_delete(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004247 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004248
4249 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004250 fib_table_lookup_exact_match(fib_index, &local_pfx),
4251 "10.10.10.10/24 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004252
4253 /*
4254 * -2 entries and -2 non-shared path-list
4255 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004256 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004257 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004258 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004259 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004260 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004261 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004262
4263 /*
4264 * Last but not least, remove the VRF
4265 */
4266 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4267 FIB_PROTOCOL_IP4,
4268 FIB_SOURCE_API)),
4269 "NO API Source'd prefixes");
4270 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4271 FIB_PROTOCOL_IP4,
4272 FIB_SOURCE_RR)),
4273 "NO RR Source'd prefixes");
4274 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4275 FIB_PROTOCOL_IP4,
4276 FIB_SOURCE_INTERFACE)),
4277 "NO INterface Source'd prefixes");
4278
Neale Ranns15002542017-09-10 04:39:11 -07004279 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004280
4281 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004282 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004283 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004284 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004285 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004286 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004287 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004288 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004289 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004290 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004291 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4292 pool_elts(load_balance_pool));
Neale Rannsf068c3e2018-01-03 04:18:48 -08004293 FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
4294 pool_elts(dvr_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004295
Neale Ranns2303cb12018-02-21 04:57:17 -08004296 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004297}
4298
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004299static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004300fib_test_v6 (void)
4301{
4302 /*
4303 * In the default table check for the presence and correct forwarding
4304 * of the special entries
4305 */
4306 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4307 const dpo_id_t *dpo, *dpo_drop;
4308 const ip_adjacency_t *adj;
4309 const receive_dpo_t *rd;
4310 test_main_t *tm;
4311 u32 fib_index;
Neale Ranns2303cb12018-02-21 04:57:17 -08004312 int ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004313
Neale Ranns2303cb12018-02-21 04:57:17 -08004314 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004315 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004316 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004317
4318 /* via 2001:0:0:1::2 */
4319 ip46_address_t nh_2001_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004320 .ip6 = {
4321 .as_u64 = {
4322 [0] = clib_host_to_net_u64(0x2001000000000001),
4323 [1] = clib_host_to_net_u64(0x0000000000000002),
4324 },
4325 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004326 };
4327
4328 tm = &test_main;
4329
4330 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4331
4332 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004333 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4334 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004335
4336 for (ii = 0; ii < 4; ii++)
4337 {
Neale Ranns2303cb12018-02-21 04:57:17 -08004338 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004339 }
4340
4341 fib_prefix_t pfx_0_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004342 .fp_len = 0,
4343 .fp_proto = FIB_PROTOCOL_IP6,
4344 .fp_addr = {
4345 .ip6 = {
4346 {0, 0},
4347 },
4348 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004349 };
4350
4351 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4352 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4353 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004354 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004355
4356 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4357 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004358 &ip6_main,
4359 1,
4360 &pfx_0_0.fp_addr.ip6)),
4361 "default-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004362
4363 // FIXME - check specials.
4364
4365 /*
4366 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004367 * each with 2 entries and a v6 mfib with 4 path-lists.
4368 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004369 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004370#define ENPS (5+4)
Jakub Grajciar7b867a82017-12-08 16:28:42 +01004371 u32 PNPS = (5+4+4);
4372 /*
4373 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
4374 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004375 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004376 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004377 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004378 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004379 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004380
4381 /*
4382 * add interface routes.
4383 * validate presence of /64 attached and /128 recieve.
4384 * test for the presence of the receive address in the glean and local adj
4385 *
4386 * receive on 2001:0:0:1::1/128
4387 */
4388 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004389 .fp_len = 64,
4390 .fp_proto = FIB_PROTOCOL_IP6,
4391 .fp_addr = {
4392 .ip6 = {
4393 .as_u64 = {
4394 [0] = clib_host_to_net_u64(0x2001000000000001),
4395 [1] = clib_host_to_net_u64(0x0000000000000001),
4396 },
4397 },
4398 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004399 };
4400
4401 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004402 FIB_SOURCE_INTERFACE,
4403 (FIB_ENTRY_FLAG_CONNECTED |
4404 FIB_ENTRY_FLAG_ATTACHED),
4405 DPO_PROTO_IP6,
4406 NULL,
4407 tm->hw[0]->sw_if_index,
4408 ~0,
4409 1,
4410 NULL,
4411 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004412 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4413
4414 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4415
4416 ai = fib_entry_get_adj(fei);
4417 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4418 adj = adj_get(ai);
4419 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004420 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004421 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004422 &adj->sub_type.glean.receive_addr)),
4423 "attached interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004424 dpo = fib_entry_contribute_ip_forwarding(fei);
4425 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004426 &ip6_main,
4427 1,
4428 &local_pfx.fp_addr.ip6)),
4429 "attached-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004430
4431 local_pfx.fp_len = 128;
4432 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004433 FIB_SOURCE_INTERFACE,
4434 (FIB_ENTRY_FLAG_CONNECTED |
4435 FIB_ENTRY_FLAG_LOCAL),
4436 DPO_PROTO_IP6,
4437 NULL,
4438 tm->hw[0]->sw_if_index,
4439 ~0, // invalid fib index
4440 1,
4441 NULL,
4442 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004443 fei = fib_table_lookup(fib_index, &local_pfx);
4444
4445 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4446
4447 dpo = fib_entry_contribute_ip_forwarding(fei);
4448 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4449 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004450 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004451 rd = receive_dpo_get(dpo->dpoi_index);
4452
4453 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004454 &rd->rd_addr)),
4455 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004456
4457 dpo = fib_entry_contribute_ip_forwarding(fei);
4458 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004459 &ip6_main,
4460 1,
4461 &local_pfx.fp_addr.ip6)),
4462 "local-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004463
4464 /*
4465 * +2 entries. +2 unshared path-lists
4466 */
4467 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004468 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004469 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004470 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004471 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004472
4473 /*
4474 * Modify the default route to be via an adj not yet known.
4475 * this sources the defalut route with the API source, which is
4476 * a higher preference to the DEFAULT_ROUTE source
4477 */
4478 fib_table_entry_path_add(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004479 FIB_SOURCE_API,
4480 FIB_ENTRY_FLAG_NONE,
4481 DPO_PROTO_IP6,
4482 &nh_2001_2,
4483 tm->hw[0]->sw_if_index,
4484 ~0,
4485 1,
4486 NULL,
4487 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004488 fei = fib_table_lookup(fib_index, &pfx_0_0);
4489
4490 FIB_TEST((fei == dfrt), "default route same index");
4491 ai = fib_entry_get_adj(fei);
4492 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4493 adj = adj_get(ai);
4494 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004495 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004496 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004497 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004498
4499 /*
4500 * find the adj in the shared db
4501 */
4502 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004503 VNET_LINK_IP6,
4504 &nh_2001_2,
4505 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004506 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4507 adj_unlock(locked_ai);
4508
4509 /*
4510 * no more entires. +1 shared path-list
4511 */
4512 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004513 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004514 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004515 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004516 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004517 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004518
4519 /*
4520 * remove the API source from the default route. We expected
4521 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4522 */
4523 fib_table_entry_path_remove(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004524 FIB_SOURCE_API,
4525 DPO_PROTO_IP6,
4526 &nh_2001_2,
4527 tm->hw[0]->sw_if_index,
4528 ~0,
4529 1,
4530 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004531 fei = fib_table_lookup(fib_index, &pfx_0_0);
4532
4533 FIB_TEST((fei == dfrt), "default route same index");
4534 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004535 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004536
4537 /*
4538 * no more entires. -1 shared path-list
4539 */
4540 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004541 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004542 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004543 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004544 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004545 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004546
4547 /*
4548 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4549 */
4550 fib_prefix_t pfx_2001_1_2_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004551 .fp_len = 128,
4552 .fp_proto = FIB_PROTOCOL_IP6,
4553 .fp_addr = {
4554 .ip6 = {
4555 .as_u64 = {
4556 [0] = clib_host_to_net_u64(0x2001000000000001),
4557 [1] = clib_host_to_net_u64(0x0000000000000002),
4558 },
4559 },
4560 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004561 };
4562 fib_prefix_t pfx_2001_1_3_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004563 .fp_len = 128,
4564 .fp_proto = FIB_PROTOCOL_IP6,
4565 .fp_addr = {
4566 .ip6 = {
4567 .as_u64 = {
4568 [0] = clib_host_to_net_u64(0x2001000000000001),
4569 [1] = clib_host_to_net_u64(0x0000000000000003),
4570 },
4571 },
4572 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004573 };
4574 u8 eth_addr[] = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004575 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004576 };
4577
4578 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004579 VNET_LINK_IP6,
4580 &pfx_2001_1_2_s_128.fp_addr,
4581 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004582 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4583 adj = adj_get(ai_01);
4584 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004585 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004586 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004587 &adj->sub_type.nbr.next_hop)),
4588 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004589
Neale Rannsb80c5362016-10-08 13:03:40 +01004590 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004591 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004592 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004593 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004594 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004595 &adj->sub_type.nbr.next_hop)),
4596 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004597
Neale Ranns81424992017-05-18 03:03:22 -07004598 fib_table_entry_path_add(fib_index,
4599 &pfx_2001_1_2_s_128,
4600 FIB_SOURCE_ADJ,
4601 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004602 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004603 &pfx_2001_1_2_s_128.fp_addr,
4604 tm->hw[0]->sw_if_index,
4605 ~0,
4606 1,
4607 NULL,
4608 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004609
4610 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4611 ai = fib_entry_get_adj(fei);
4612 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4613
4614 eth_addr[5] = 0xb2;
4615
4616 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004617 VNET_LINK_IP6,
4618 &pfx_2001_1_3_s_128.fp_addr,
4619 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004620 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4621 adj = adj_get(ai_02);
4622 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004623 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004624 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004625 &adj->sub_type.nbr.next_hop)),
4626 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004627
Neale Rannsb80c5362016-10-08 13:03:40 +01004628 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004629 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004630 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004631 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004632 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004633 &adj->sub_type.nbr.next_hop)),
4634 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004635 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4636
Neale Ranns81424992017-05-18 03:03:22 -07004637 fib_table_entry_path_add(fib_index,
4638 &pfx_2001_1_3_s_128,
4639 FIB_SOURCE_ADJ,
4640 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004641 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004642 &pfx_2001_1_3_s_128.fp_addr,
4643 tm->hw[0]->sw_if_index,
4644 ~0,
4645 1,
4646 NULL,
4647 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004648
4649 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4650 ai = fib_entry_get_adj(fei);
4651 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4652
4653 /*
4654 * +2 entries, +2 unshread path-lists.
4655 */
4656 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004657 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004658 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004659 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004660 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004661 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004662
4663 /*
4664 * Add a 2 routes via the first ADJ. ensure path-list sharing
4665 */
4666 fib_prefix_t pfx_2001_a_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004667 .fp_len = 64,
4668 .fp_proto = FIB_PROTOCOL_IP6,
4669 .fp_addr = {
4670 .ip6 = {
4671 .as_u64 = {
4672 [0] = clib_host_to_net_u64(0x200100000000000a),
4673 [1] = clib_host_to_net_u64(0x0000000000000000),
4674 },
4675 },
4676 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004677 };
4678 fib_prefix_t pfx_2001_b_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004679 .fp_len = 64,
4680 .fp_proto = FIB_PROTOCOL_IP6,
4681 .fp_addr = {
4682 .ip6 = {
4683 .as_u64 = {
4684 [0] = clib_host_to_net_u64(0x200100000000000b),
4685 [1] = clib_host_to_net_u64(0x0000000000000000),
4686 },
4687 },
4688 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004689 };
4690
4691 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004692 &pfx_2001_a_s_64,
4693 FIB_SOURCE_API,
4694 FIB_ENTRY_FLAG_NONE,
4695 DPO_PROTO_IP6,
4696 &nh_2001_2,
4697 tm->hw[0]->sw_if_index,
4698 ~0,
4699 1,
4700 NULL,
4701 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004702 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4703 ai = fib_entry_get_adj(fei);
4704 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4705 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004706 &pfx_2001_b_s_64,
4707 FIB_SOURCE_API,
4708 FIB_ENTRY_FLAG_NONE,
4709 DPO_PROTO_IP6,
4710 &nh_2001_2,
4711 tm->hw[0]->sw_if_index,
4712 ~0,
4713 1,
4714 NULL,
4715 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004716 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4717 ai = fib_entry_get_adj(fei);
4718 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4719
4720 /*
4721 * +2 entries, +1 shared path-list.
4722 */
4723 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004724 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004725 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004726 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004727 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004728 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004729
4730 /*
4731 * add a v4 prefix via a v6 next-hop
4732 */
4733 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004734 .fp_len = 32,
4735 .fp_proto = FIB_PROTOCOL_IP4,
4736 .fp_addr = {
4737 .ip4.as_u32 = 0x01010101,
4738 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004739 };
4740 fei = fib_table_entry_path_add(0, // default table
Neale Ranns2303cb12018-02-21 04:57:17 -08004741 &pfx_1_1_1_1_s_32,
4742 FIB_SOURCE_API,
4743 FIB_ENTRY_FLAG_NONE,
4744 DPO_PROTO_IP6,
4745 &nh_2001_2,
4746 tm->hw[0]->sw_if_index,
4747 ~0,
4748 1,
4749 NULL,
4750 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004751 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
Neale Ranns2303cb12018-02-21 04:57:17 -08004752 "1.1.1.1/32 o v6 route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004753 ai = fib_entry_get_adj(fei);
4754 adj = adj_get(ai);
4755 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
Neale Ranns2303cb12018-02-21 04:57:17 -08004756 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004757 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns2303cb12018-02-21 04:57:17 -08004758 "1.1.1.1/32 ADJ-adj is link type v4");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004759 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
Neale Ranns2303cb12018-02-21 04:57:17 -08004760 "1.1.1.1/32 ADJ-adj is NH proto v6");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004761 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4762
4763 /*
4764 * An attached route
4765 */
4766 fib_prefix_t pfx_2001_c_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004767 .fp_len = 64,
4768 .fp_proto = FIB_PROTOCOL_IP6,
4769 .fp_addr = {
4770 .ip6 = {
4771 .as_u64 = {
4772 [0] = clib_host_to_net_u64(0x200100000000000c),
4773 [1] = clib_host_to_net_u64(0x0000000000000000),
4774 },
4775 },
4776 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004777 };
4778 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004779 &pfx_2001_c_s_64,
4780 FIB_SOURCE_CLI,
4781 FIB_ENTRY_FLAG_ATTACHED,
4782 DPO_PROTO_IP6,
4783 NULL,
4784 tm->hw[0]->sw_if_index,
4785 ~0,
4786 1,
4787 NULL,
4788 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004789 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4790 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4791 ai = fib_entry_get_adj(fei);
4792 adj = adj_get(ai);
4793 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
Neale Ranns2303cb12018-02-21 04:57:17 -08004794 "2001:0:0:c/64 attached resolves via glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004795
4796 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004797 &pfx_2001_c_s_64,
4798 FIB_SOURCE_CLI,
4799 DPO_PROTO_IP6,
4800 NULL,
4801 tm->hw[0]->sw_if_index,
4802 ~0,
4803 1,
4804 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004805 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4806 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4807
4808 /*
4809 * Shutdown the interface on which we have a connected and through
4810 * which the routes are reachable.
4811 * This will result in the connected, adj-fibs, and routes linking to drop
4812 * The local/for-us prefix continues to receive.
4813 */
4814 clib_error_t * error;
4815
4816 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004817 tm->hw[0]->sw_if_index,
4818 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004819 FIB_TEST((NULL == error), "Interface shutdown OK");
4820
4821 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4822 dpo = fib_entry_contribute_ip_forwarding(fei);
4823 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004824 "2001::b/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004825
4826 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4827 dpo = fib_entry_contribute_ip_forwarding(fei);
4828 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004829 "2001::a/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004830 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4831 dpo = fib_entry_contribute_ip_forwarding(fei);
4832 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004833 "2001:0:0:1::3/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004834 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4835 dpo = fib_entry_contribute_ip_forwarding(fei);
4836 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004837 "2001:0:0:1::2/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004838 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4839 dpo = fib_entry_contribute_ip_forwarding(fei);
4840 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004841 "2001:0:0:1::1/128 not drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004842 local_pfx.fp_len = 64;
4843 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4844 dpo = fib_entry_contribute_ip_forwarding(fei);
4845 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004846 "2001:0:0:1/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004847
4848 /*
4849 * no change
4850 */
4851 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004852 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004853 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004854 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004855 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004856 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004857
4858 /*
4859 * shutdown one of the other interfaces, then add a connected.
4860 * and swap one of the routes to it.
4861 */
4862 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004863 tm->hw[1]->sw_if_index,
4864 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004865 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4866
4867 fib_prefix_t connected_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004868 .fp_len = 64,
4869 .fp_proto = FIB_PROTOCOL_IP6,
4870 .fp_addr = {
4871 .ip6 = {
4872 /* 2001:0:0:2::1/64 */
4873 .as_u64 = {
4874 [0] = clib_host_to_net_u64(0x2001000000000002),
4875 [1] = clib_host_to_net_u64(0x0000000000000001),
4876 },
4877 },
4878 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004879 };
4880 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004881 FIB_SOURCE_INTERFACE,
4882 (FIB_ENTRY_FLAG_CONNECTED |
4883 FIB_ENTRY_FLAG_ATTACHED),
4884 DPO_PROTO_IP6,
4885 NULL,
4886 tm->hw[1]->sw_if_index,
4887 ~0,
4888 1,
4889 NULL,
4890 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004891 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4892 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4893 dpo = fib_entry_contribute_ip_forwarding(fei);
4894 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4895 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4896 "2001:0:0:2/64 not resolves via drop");
4897
4898 connected_pfx.fp_len = 128;
4899 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004900 FIB_SOURCE_INTERFACE,
4901 (FIB_ENTRY_FLAG_CONNECTED |
4902 FIB_ENTRY_FLAG_LOCAL),
4903 DPO_PROTO_IP6,
4904 NULL,
4905 tm->hw[0]->sw_if_index,
4906 ~0, // invalid fib index
4907 1,
4908 NULL,
4909 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004910 fei = fib_table_lookup(fib_index, &connected_pfx);
4911
4912 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4913 dpo = fib_entry_contribute_ip_forwarding(fei);
4914 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4915 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004916 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004917 rd = receive_dpo_get(dpo->dpoi_index);
4918 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004919 &rd->rd_addr)),
4920 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004921
4922 /*
4923 * +2 entries, +2 unshared path-lists
4924 */
4925 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004926 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004927 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004928 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004929 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004930 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004931
4932
4933 /*
4934 * bring the interface back up. we expected the routes to return
4935 * to normal forwarding.
4936 */
4937 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004938 tm->hw[0]->sw_if_index,
4939 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004940 FIB_TEST((NULL == error), "Interface bring-up OK");
4941 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4942 ai = fib_entry_get_adj(fei);
4943 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4944 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4945 ai = fib_entry_get_adj(fei);
4946 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4947 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4948 ai = fib_entry_get_adj(fei);
4949 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4950 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4951 ai = fib_entry_get_adj(fei);
4952 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4953 local_pfx.fp_len = 64;
4954 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4955 ai = fib_entry_get_adj(fei);
4956 adj = adj_get(ai);
4957 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004958 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004959
4960 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004961 * Same test as above, but this time the HW interface goes down
4962 */
4963 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004964 tm->hw_if_indicies[0],
4965 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00004966 FIB_TEST((NULL == error), "Interface shutdown OK");
4967
4968 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4969 dpo = fib_entry_contribute_ip_forwarding(fei);
4970 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004971 "2001::b/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004972 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4973 dpo = fib_entry_contribute_ip_forwarding(fei);
4974 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004975 "2001::a/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004976 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4977 dpo = fib_entry_contribute_ip_forwarding(fei);
4978 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004979 "2001:0:0:1::3/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004980 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4981 dpo = fib_entry_contribute_ip_forwarding(fei);
4982 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004983 "2001:0:0:1::2/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004984 local_pfx.fp_len = 128;
4985 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4986 dpo = fib_entry_contribute_ip_forwarding(fei);
4987 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004988 "2001:0:0:1::1/128 not drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004989 local_pfx.fp_len = 64;
4990 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4991 dpo = fib_entry_contribute_ip_forwarding(fei);
4992 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004993 "2001:0:0:1/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004994
4995 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004996 tm->hw_if_indicies[0],
4997 VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00004998 FIB_TEST((NULL == error), "Interface bring-up OK");
4999 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5000 ai = fib_entry_get_adj(fei);
5001 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
5002 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5003 ai = fib_entry_get_adj(fei);
5004 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
5005 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5006 ai = fib_entry_get_adj(fei);
5007 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
5008 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5009 ai = fib_entry_get_adj(fei);
5010 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
5011 local_pfx.fp_len = 64;
5012 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5013 ai = fib_entry_get_adj(fei);
5014 adj = adj_get(ai);
5015 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08005016 "attached interface adj is glean");
Neale Ranns8b37b872016-11-21 12:25:22 +00005017
5018 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005019 * Delete the interface that the routes reolve through.
5020 * Again no routes are removed. They all point to drop.
5021 *
5022 * This is considered an error case. The control plane should
5023 * not remove interfaces through which routes resolve, but
5024 * such things can happen. ALL affected routes will drop.
5025 */
5026 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
5027
5028 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5029 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5030 "2001::b/64 resolves via drop");
5031 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5032 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5033 "2001::b/64 resolves via drop");
5034 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5035 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5036 "2001:0:0:1::3/64 resolves via drop");
5037 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5038 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5039 "2001:0:0:1::2/64 resolves via drop");
5040 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5041 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5042 "2001:0:0:1::1/128 is drop");
5043 local_pfx.fp_len = 64;
5044 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5045 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5046 "2001:0:0:1/64 resolves via drop");
5047
5048 /*
5049 * no change
5050 */
5051 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005052 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005053 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005054 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005055 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005056 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005057
5058 /*
5059 * Add the interface back. routes stay unresolved.
5060 */
5061 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005062 test_interface_device_class.index,
5063 0 /* instance */,
5064 hw_address,
5065 &tm->hw_if_indicies[0],
5066 /* flag change */ 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005067
5068 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5069 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5070 "2001::b/64 resolves via drop");
5071 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5072 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5073 "2001::b/64 resolves via drop");
5074 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5075 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5076 "2001:0:0:1::3/64 resolves via drop");
5077 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5078 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5079 "2001:0:0:1::2/64 resolves via drop");
5080 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5081 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5082 "2001:0:0:1::1/128 is drop");
5083 local_pfx.fp_len = 64;
5084 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5085 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5086 "2001:0:0:1/64 resolves via drop");
5087
5088 /*
5089 * CLEANUP ALL the routes
5090 */
5091 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005092 &pfx_2001_c_s_64,
5093 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005094 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005095 &pfx_2001_a_s_64,
5096 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005097 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005098 &pfx_2001_b_s_64,
5099 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005100 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005101 &pfx_2001_1_3_s_128,
5102 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005103 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005104 &pfx_2001_1_2_s_128,
5105 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005106 local_pfx.fp_len = 64;
5107 fib_table_entry_delete(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005108 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005109 local_pfx.fp_len = 128;
5110 fib_table_entry_special_remove(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005111 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005112 connected_pfx.fp_len = 64;
5113 fib_table_entry_delete(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005114 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005115 connected_pfx.fp_len = 128;
5116 fib_table_entry_special_remove(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005117 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005118
5119 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005120 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5121 "2001::a/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005122 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005123 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5124 "2001::b/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005125 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005126 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5127 "2001:0:0:1::3/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005128 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005129 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5130 "2001:0:0:1::3/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005131 local_pfx.fp_len = 64;
5132 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005133 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5134 "2001:0:0:1/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005135 local_pfx.fp_len = 128;
5136 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005137 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5138 "2001:0:0:1::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005139 connected_pfx.fp_len = 64;
5140 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005141 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5142 "2001:0:0:2/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005143 connected_pfx.fp_len = 128;
5144 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005145 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5146 "2001:0:0:2::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005147
5148 /*
5149 * -8 entries. -7 path-lists (1 was shared).
5150 */
5151 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005152 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005153 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005154 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005155 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005156 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005157
5158 /*
5159 * now remove the VRF
5160 */
Neale Ranns15002542017-09-10 04:39:11 -07005161 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005162
5163 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005164 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005165 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005166 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005167 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005168 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005169
5170 adj_unlock(ai_02);
5171 adj_unlock(ai_01);
5172
5173 /*
5174 * return the interfaces to up state
5175 */
5176 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005177 tm->hw[0]->sw_if_index,
5178 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005179 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005180 tm->hw[1]->sw_if_index,
5181 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005182
5183 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005184 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005185
Neale Ranns2303cb12018-02-21 04:57:17 -08005186 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005187}
5188
5189/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005190 * Test Attached Exports
5191 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005192static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005193fib_test_ae (void)
5194{
5195 const dpo_id_t *dpo, *dpo_drop;
5196 const u32 fib_index = 0;
5197 fib_node_index_t fei;
5198 test_main_t *tm;
5199 ip4_main_t *im;
Neale Ranns2303cb12018-02-21 04:57:17 -08005200 int res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005201
Neale Ranns2303cb12018-02-21 04:57:17 -08005202 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005203 tm = &test_main;
5204 im = &ip4_main;
5205
5206 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005207 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005208
5209 /*
5210 * add interface routes. We'll assume this works. It's more rigorously
5211 * tested elsewhere.
5212 */
5213 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005214 .fp_len = 24,
5215 .fp_proto = FIB_PROTOCOL_IP4,
5216 .fp_addr = {
5217 .ip4 = {
5218 /* 10.10.10.10 */
5219 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5220 },
5221 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005222 };
5223
5224 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5225 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5226
5227 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5228
5229 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005230 FIB_SOURCE_INTERFACE,
5231 (FIB_ENTRY_FLAG_CONNECTED |
5232 FIB_ENTRY_FLAG_ATTACHED),
5233 DPO_PROTO_IP4,
5234 NULL,
5235 tm->hw[0]->sw_if_index,
5236 ~0,
5237 1,
5238 NULL,
5239 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005240 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5241 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005242 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005243
5244 local_pfx.fp_len = 32;
5245 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005246 FIB_SOURCE_INTERFACE,
5247 (FIB_ENTRY_FLAG_CONNECTED |
5248 FIB_ENTRY_FLAG_LOCAL),
5249 DPO_PROTO_IP4,
5250 NULL,
5251 tm->hw[0]->sw_if_index,
5252 ~0, // invalid fib index
5253 1,
5254 NULL,
5255 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005256 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5257
5258 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005259 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005260
5261 /*
5262 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5263 */
5264 fib_prefix_t pfx_10_10_10_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005265 .fp_len = 32,
5266 .fp_proto = FIB_PROTOCOL_IP4,
5267 .fp_addr = {
5268 /* 10.10.10.1 */
5269 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5270 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005271 };
5272 fib_node_index_t ai;
5273
Neale Ranns81424992017-05-18 03:03:22 -07005274 fib_table_entry_path_add(fib_index,
5275 &pfx_10_10_10_1_s_32,
5276 FIB_SOURCE_ADJ,
5277 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005278 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005279 &pfx_10_10_10_1_s_32.fp_addr,
5280 tm->hw[0]->sw_if_index,
5281 ~0, // invalid fib index
5282 1,
5283 NULL,
5284 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005285
5286 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5287 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5288 ai = fib_entry_get_adj(fei);
5289
5290 /*
5291 * create another FIB table into which routes will be imported
5292 */
5293 u32 import_fib_index1;
5294
Neale Ranns15002542017-09-10 04:39:11 -07005295 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5296 11,
5297 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005298
5299 /*
5300 * Add an attached route in the import FIB
5301 */
5302 local_pfx.fp_len = 24;
5303 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005304 &local_pfx,
5305 FIB_SOURCE_API,
5306 FIB_ENTRY_FLAG_NONE,
5307 DPO_PROTO_IP4,
5308 NULL,
5309 tm->hw[0]->sw_if_index,
5310 ~0, // invalid fib index
5311 1,
5312 NULL,
5313 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005314 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5315 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5316
5317 /*
5318 * check for the presence of the adj-fibs in the import table
5319 */
5320 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5321 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5322 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005323 "adj-fib1 Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005324
5325 /*
5326 * check for the presence of the local in the import table
5327 */
5328 local_pfx.fp_len = 32;
5329 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5330 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5331
5332 /*
5333 * Add another adj-fin in the export table. Expect this
5334 * to get magically exported;
5335 */
5336 fib_prefix_t pfx_10_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005337 .fp_len = 32,
5338 .fp_proto = FIB_PROTOCOL_IP4,
5339 .fp_addr = {
5340 /* 10.10.10.2 */
5341 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5342 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005343 };
5344
Neale Ranns81424992017-05-18 03:03:22 -07005345 fib_table_entry_path_add(fib_index,
5346 &pfx_10_10_10_2_s_32,
5347 FIB_SOURCE_ADJ,
5348 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005349 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005350 &pfx_10_10_10_2_s_32.fp_addr,
5351 tm->hw[0]->sw_if_index,
5352 ~0, // invalid fib index
5353 1,
5354 NULL,
5355 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005356 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5357 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5358 ai = fib_entry_get_adj(fei);
5359
5360 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5361 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5362 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005363 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005364 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5365 "ADJ-fib2 imported flags %d",
5366 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005367
5368 /*
5369 * create a 2nd FIB table into which routes will be imported
5370 */
5371 u32 import_fib_index2;
5372
Neale Ranns15002542017-09-10 04:39:11 -07005373 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5374 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005375
5376 /*
5377 * Add an attached route in the import FIB
5378 */
5379 local_pfx.fp_len = 24;
5380 fib_table_entry_update_one_path(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005381 &local_pfx,
5382 FIB_SOURCE_API,
5383 FIB_ENTRY_FLAG_NONE,
5384 DPO_PROTO_IP4,
5385 NULL,
5386 tm->hw[0]->sw_if_index,
5387 ~0, // invalid fib index
5388 1,
5389 NULL,
5390 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005391 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5392 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5393
5394 /*
5395 * check for the presence of all the adj-fibs and local in the import table
5396 */
5397 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5398 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5399 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5400 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5401 local_pfx.fp_len = 32;
5402 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5403 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5404
5405 /*
5406 * add a 3rd adj-fib. expect it to be exported to both tables.
5407 */
5408 fib_prefix_t pfx_10_10_10_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005409 .fp_len = 32,
5410 .fp_proto = FIB_PROTOCOL_IP4,
5411 .fp_addr = {
5412 /* 10.10.10.3 */
5413 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5414 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005415 };
5416
Neale Ranns81424992017-05-18 03:03:22 -07005417 fib_table_entry_path_add(fib_index,
5418 &pfx_10_10_10_3_s_32,
5419 FIB_SOURCE_ADJ,
5420 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005421 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005422 &pfx_10_10_10_3_s_32.fp_addr,
5423 tm->hw[0]->sw_if_index,
5424 ~0, // invalid fib index
5425 1,
5426 NULL,
5427 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005428 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5429 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5430 ai = fib_entry_get_adj(fei);
5431
5432 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5433 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5434 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005435 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005436 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5437 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5438 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005439 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005440
5441 /*
5442 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5443 */
5444 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005445 &pfx_10_10_10_3_s_32,
5446 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005447
5448 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5449 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5450
5451 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5452 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5453
5454 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5455 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5456
5457 /*
5458 * remove the attached route from the 2nd FIB. expect the imported
5459 * entires to be removed
5460 */
5461 local_pfx.fp_len = 24;
5462 fib_table_entry_delete(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005463 &local_pfx,
5464 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005465 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5466 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5467
5468 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5469 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5470 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5471 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5472 local_pfx.fp_len = 32;
5473 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5474 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5475
5476 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5477 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5478 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5479 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5480 local_pfx.fp_len = 32;
5481 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5482 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5483
5484 /*
5485 * modify the route in FIB1 so it is no longer attached. expect the imported
5486 * entires to be removed
5487 */
5488 local_pfx.fp_len = 24;
5489 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005490 &local_pfx,
5491 FIB_SOURCE_API,
5492 FIB_ENTRY_FLAG_NONE,
5493 DPO_PROTO_IP4,
5494 &pfx_10_10_10_2_s_32.fp_addr,
5495 tm->hw[0]->sw_if_index,
5496 ~0, // invalid fib index
5497 1,
5498 NULL,
5499 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005500 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5501 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5502 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5503 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5504 local_pfx.fp_len = 32;
5505 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5506 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5507
5508 /*
5509 * modify it back to attached. expect the adj-fibs back
5510 */
5511 local_pfx.fp_len = 24;
5512 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005513 &local_pfx,
5514 FIB_SOURCE_API,
5515 FIB_ENTRY_FLAG_NONE,
5516 DPO_PROTO_IP4,
5517 NULL,
5518 tm->hw[0]->sw_if_index,
5519 ~0, // invalid fib index
5520 1,
5521 NULL,
5522 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005523 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5524 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5525 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5526 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5527 local_pfx.fp_len = 32;
5528 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5529 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5530
5531 /*
5532 * add a covering attached next-hop for the interface address, so we have
5533 * a valid adj to find when we check the forwarding tables
5534 */
5535 fib_prefix_t pfx_10_0_0_0_s_8 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005536 .fp_len = 8,
5537 .fp_proto = FIB_PROTOCOL_IP4,
5538 .fp_addr = {
5539 /* 10.0.0.0 */
5540 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5541 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005542 };
5543
5544 fei = fib_table_entry_update_one_path(fib_index,
5545 &pfx_10_0_0_0_s_8,
5546 FIB_SOURCE_API,
5547 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005548 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005549 &pfx_10_10_10_3_s_32.fp_addr,
5550 tm->hw[0]->sw_if_index,
5551 ~0, // invalid fib index
5552 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005553 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005554 FIB_ROUTE_PATH_FLAG_NONE);
5555 dpo = fib_entry_contribute_ip_forwarding(fei);
5556
5557 /*
5558 * remove the route in the export fib. expect the adj-fibs to be removed
5559 */
5560 local_pfx.fp_len = 24;
5561 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005562 &local_pfx,
5563 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005564
5565 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5566 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5567 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5568 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5569 local_pfx.fp_len = 32;
5570 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5571 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5572
5573 /*
5574 * the adj-fibs in the export VRF are present in the FIB table,
5575 * but not installed in forwarding, since they have no attached cover.
5576 * Consequently a lookup in the MTRIE gives the adj for the covering
5577 * route 10.0.0.0/8.
5578 */
5579 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5580 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5581
5582 index_t lbi;
5583 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5584 FIB_TEST(lbi == dpo->dpoi_index,
5585 "10.10.10.1 forwards on \n%U not \n%U",
5586 format_load_balance, lbi, 0,
5587 format_dpo_id, dpo, 0);
5588 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5589 FIB_TEST(lbi == dpo->dpoi_index,
5590 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5591 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5592 FIB_TEST(lbi == dpo->dpoi_index,
5593 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5594
5595 /*
5596 * add the export prefix back, but not as attached.
5597 * No adj-fibs in export nor import tables
5598 */
5599 local_pfx.fp_len = 24;
5600 fei = fib_table_entry_update_one_path(fib_index,
5601 &local_pfx,
5602 FIB_SOURCE_API,
5603 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005604 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005605 &pfx_10_10_10_1_s_32.fp_addr,
5606 tm->hw[0]->sw_if_index,
5607 ~0, // invalid fib index
5608 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005609 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005610 FIB_ROUTE_PATH_FLAG_NONE);
5611 dpo = fib_entry_contribute_ip_forwarding(fei);
5612
5613 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5614 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5615 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5616 FIB_TEST(lbi == dpo->dpoi_index,
5617 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5618 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5619 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5620 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5621 FIB_TEST(lbi == dpo->dpoi_index,
5622 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5623
5624 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5625 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5626 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5627 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5628 local_pfx.fp_len = 32;
5629 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5630 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5631
5632 /*
5633 * modify the export prefix so it is attached. expect all covereds to return
5634 */
5635 local_pfx.fp_len = 24;
5636 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005637 &local_pfx,
5638 FIB_SOURCE_API,
5639 FIB_ENTRY_FLAG_NONE,
5640 DPO_PROTO_IP4,
5641 NULL,
5642 tm->hw[0]->sw_if_index,
5643 ~0, // invalid fib index
5644 1,
5645 NULL,
5646 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005647
5648 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5649 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5650 dpo = fib_entry_contribute_ip_forwarding(fei);
5651 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005652 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005653 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5654 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5655 local_pfx.fp_len = 32;
5656 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5657 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5658 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5659 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5660 dpo = fib_entry_contribute_ip_forwarding(fei);
5661 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005662 "Adj-fib1 is not drop in export: %U %U",
5663 format_dpo_id, dpo, 0,
5664 format_dpo_id, load_balance_get_bucket(dpo->dpoi_index, 0), 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005665 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5666 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5667 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5668 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5669 local_pfx.fp_len = 32;
5670 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5671 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5672
5673 /*
5674 * modify the export prefix so connected. no change.
5675 */
5676 local_pfx.fp_len = 24;
5677 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005678 FIB_SOURCE_INTERFACE,
5679 (FIB_ENTRY_FLAG_CONNECTED |
5680 FIB_ENTRY_FLAG_ATTACHED),
5681 DPO_PROTO_IP4,
5682 NULL,
5683 tm->hw[0]->sw_if_index,
5684 ~0,
5685 1,
5686 NULL,
5687 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005688
5689 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5690 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5691 dpo = fib_entry_contribute_ip_forwarding(fei);
5692 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005693 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005694 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5695 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5696 local_pfx.fp_len = 32;
5697 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5698 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5699 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5700 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5701 dpo = fib_entry_contribute_ip_forwarding(fei);
5702 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005703 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005704 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5705 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5706 local_pfx.fp_len = 32;
5707 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5708 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5709
5710 /*
5711 * CLEANUP
5712 */
5713 fib_table_entry_delete(fib_index,
5714 &pfx_10_0_0_0_s_8,
5715 FIB_SOURCE_API);
5716 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005717 &pfx_10_10_10_1_s_32,
5718 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005719 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005720 &pfx_10_10_10_2_s_32,
5721 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005722 local_pfx.fp_len = 32;
5723 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005724 &local_pfx,
5725 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005726 local_pfx.fp_len = 24;
5727 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005728 &local_pfx,
5729 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005730 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005731 &local_pfx,
5732 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005733 local_pfx.fp_len = 24;
5734 fib_table_entry_delete(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005735 &local_pfx,
5736 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005737
Neale Ranns15002542017-09-10 04:39:11 -07005738 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5739 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005740
5741 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005742 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005743
Neale Ranns2303cb12018-02-21 04:57:17 -08005744 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005745}
5746
Neale Ranns57b58602017-07-15 07:37:25 -07005747/*
5748 * Test Path Preference
5749 */
5750static int
5751fib_test_pref (void)
5752{
5753 test_main_t *tm = &test_main;
Neale Ranns2303cb12018-02-21 04:57:17 -08005754 int res;
Neale Ranns57b58602017-07-15 07:37:25 -07005755
Neale Ranns2303cb12018-02-21 04:57:17 -08005756 res = 0;
Neale Ranns57b58602017-07-15 07:37:25 -07005757 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5758 .fp_len = 32,
5759 .fp_proto = FIB_PROTOCOL_IP4,
5760 .fp_addr = {
5761 .ip4 = {
5762 .as_u32 = clib_host_to_net_u32(0x01010101),
5763 },
5764 },
5765 };
5766
5767 /*
5768 * 2 high, 2 medium and 2 low preference non-recursive paths
5769 */
5770 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005771 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005772 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5773 .frp_fib_index = ~0,
5774 .frp_weight = 1,
5775 .frp_preference = 0,
5776 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5777 .frp_addr = {
5778 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5779 },
5780 };
5781 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005782 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005783 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5784 .frp_fib_index = ~0,
5785 .frp_weight = 1,
5786 .frp_preference = 0,
5787 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5788 .frp_addr = {
5789 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5790 },
5791 };
5792 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005793 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005794 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5795 .frp_fib_index = ~0,
5796 .frp_weight = 1,
5797 .frp_preference = 1,
5798 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5799 .frp_addr = {
5800 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5801 },
5802 };
5803 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005804 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005805 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5806 .frp_fib_index = ~0,
5807 .frp_weight = 1,
5808 .frp_preference = 1,
5809 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5810 .frp_addr = {
5811 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5812 },
5813 };
5814 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005815 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005816 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5817 .frp_fib_index = ~0,
5818 .frp_weight = 1,
5819 .frp_preference = 2,
5820 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5821 .frp_addr = {
5822 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5823 },
5824 };
5825 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005826 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005827 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5828 .frp_fib_index = ~0,
5829 .frp_weight = 1,
5830 .frp_preference = 2,
5831 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5832 .frp_addr = {
5833 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5834 },
5835 };
5836 fib_route_path_t *nr_paths = NULL;
5837
5838 vec_add1(nr_paths, nr_path_hi_1);
5839 vec_add1(nr_paths, nr_path_hi_2);
5840 vec_add1(nr_paths, nr_path_med_1);
5841 vec_add1(nr_paths, nr_path_med_2);
5842 vec_add1(nr_paths, nr_path_low_1);
5843 vec_add1(nr_paths, nr_path_low_2);
5844
5845 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5846 VNET_LINK_IP4,
5847 &nr_path_hi_1.frp_addr,
5848 nr_path_hi_1.frp_sw_if_index);
5849 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5850 VNET_LINK_IP4,
5851 &nr_path_hi_2.frp_addr,
5852 nr_path_hi_2.frp_sw_if_index);
5853 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5854 VNET_LINK_IP4,
5855 &nr_path_med_1.frp_addr,
5856 nr_path_med_1.frp_sw_if_index);
5857 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5858 VNET_LINK_IP4,
5859 &nr_path_med_2.frp_addr,
5860 nr_path_med_2.frp_sw_if_index);
5861 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5862 VNET_LINK_IP4,
5863 &nr_path_low_1.frp_addr,
5864 nr_path_low_1.frp_sw_if_index);
5865 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5866 VNET_LINK_IP4,
5867 &nr_path_low_2.frp_addr,
5868 nr_path_low_2.frp_sw_if_index);
5869
5870 fib_test_lb_bucket_t ip_hi_1 = {
5871 .type = FT_LB_ADJ,
5872 .adj = {
5873 .adj = ai_hi_1,
5874 },
5875 };
5876 fib_test_lb_bucket_t ip_hi_2 = {
5877 .type = FT_LB_ADJ,
5878 .adj = {
5879 .adj = ai_hi_2,
5880 },
5881 };
5882 fib_test_lb_bucket_t ip_med_1 = {
5883 .type = FT_LB_ADJ,
5884 .adj = {
5885 .adj = ai_med_1,
5886 },
5887 };
5888 fib_test_lb_bucket_t ip_med_2 = {
5889 .type = FT_LB_ADJ,
5890 .adj = {
5891 .adj = ai_med_2,
5892 },
5893 };
5894 fib_test_lb_bucket_t ip_low_1 = {
5895 .type = FT_LB_ADJ,
5896 .adj = {
5897 .adj = ai_low_1,
5898 },
5899 };
5900 fib_test_lb_bucket_t ip_low_2 = {
5901 .type = FT_LB_ADJ,
5902 .adj = {
5903 .adj = ai_low_2,
5904 },
5905 };
5906
5907 fib_node_index_t fei;
5908
5909 fei = fib_table_entry_path_add2(0,
5910 &pfx_1_1_1_1_s_32,
5911 FIB_SOURCE_API,
5912 FIB_ENTRY_FLAG_NONE,
5913 nr_paths);
5914
Neale Ranns2303cb12018-02-21 04:57:17 -08005915 FIB_TEST(!fib_test_validate_entry(fei,
5916 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5917 2,
5918 &ip_hi_1,
5919 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005920 "1.1.1.1/32 via high preference paths");
5921
5922 /*
5923 * bring down the interface on which the high preference path lie
5924 */
5925 vnet_sw_interface_set_flags(vnet_get_main(),
5926 tm->hw[0]->sw_if_index,
5927 0);
5928
Neale Ranns2303cb12018-02-21 04:57:17 -08005929 FIB_TEST(!fib_test_validate_entry(fei,
5930 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5931 2,
5932 &ip_med_1,
5933 &ip_med_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005934 "1.1.1.1/32 via medium preference paths");
5935
5936 /*
5937 * bring down the interface on which the medium preference path lie
5938 */
5939 vnet_sw_interface_set_flags(vnet_get_main(),
5940 tm->hw[1]->sw_if_index,
5941 0);
5942
Neale Ranns2303cb12018-02-21 04:57:17 -08005943 FIB_TEST(!fib_test_validate_entry(fei,
5944 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5945 2,
5946 &ip_low_1,
5947 &ip_low_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005948 "1.1.1.1/32 via low preference paths");
5949
5950 /*
5951 * bring up the interface on which the high preference path lie
5952 */
5953 vnet_sw_interface_set_flags(vnet_get_main(),
5954 tm->hw[0]->sw_if_index,
5955 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5956
Neale Ranns2303cb12018-02-21 04:57:17 -08005957 FIB_TEST(!fib_test_validate_entry(fei,
5958 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5959 2,
5960 &ip_hi_1,
5961 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005962 "1.1.1.1/32 via high preference paths");
5963
5964 /*
5965 * bring up the interface on which the medium preference path lie
5966 */
5967 vnet_sw_interface_set_flags(vnet_get_main(),
5968 tm->hw[1]->sw_if_index,
5969 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5970
Neale Ranns2303cb12018-02-21 04:57:17 -08005971 FIB_TEST(!fib_test_validate_entry(fei,
5972 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5973 2,
5974 &ip_hi_1,
5975 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005976 "1.1.1.1/32 via high preference paths");
5977
5978 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5979 fib_entry_contribute_forwarding(fei,
5980 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5981 &ip_1_1_1_1);
5982
5983 /*
5984 * 3 recursive paths of different preference
5985 */
5986 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5987 .fp_len = 32,
5988 .fp_proto = FIB_PROTOCOL_IP4,
5989 .fp_addr = {
5990 .ip4 = {
5991 .as_u32 = clib_host_to_net_u32(0x01010102),
5992 },
5993 },
5994 };
5995 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5996 .fp_len = 32,
5997 .fp_proto = FIB_PROTOCOL_IP4,
5998 .fp_addr = {
5999 .ip4 = {
6000 .as_u32 = clib_host_to_net_u32(0x01010103),
6001 },
6002 },
6003 };
6004 fei = fib_table_entry_path_add2(0,
6005 &pfx_1_1_1_2_s_32,
6006 FIB_SOURCE_API,
6007 FIB_ENTRY_FLAG_NONE,
6008 nr_paths);
6009 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
6010 fib_entry_contribute_forwarding(fei,
6011 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6012 &ip_1_1_1_2);
6013 fei = fib_table_entry_path_add2(0,
6014 &pfx_1_1_1_3_s_32,
6015 FIB_SOURCE_API,
6016 FIB_ENTRY_FLAG_NONE,
6017 nr_paths);
6018 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
6019 fib_entry_contribute_forwarding(fei,
6020 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6021 &ip_1_1_1_3);
6022
6023 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
6024 .type = FT_LB_O_LB,
6025 .lb = {
6026 .lb = ip_1_1_1_1.dpoi_index,
6027 },
6028 };
6029 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
6030 .type = FT_LB_O_LB,
6031 .lb = {
6032 .lb = ip_1_1_1_2.dpoi_index,
6033 },
6034 };
6035 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
6036 .type = FT_LB_O_LB,
6037 .lb = {
6038 .lb = ip_1_1_1_3.dpoi_index,
6039 },
6040 };
6041 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07006042 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006043 .frp_sw_if_index = ~0,
6044 .frp_fib_index = 0,
6045 .frp_weight = 1,
6046 .frp_preference = 0,
6047 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6048 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6049 };
6050 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006051 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006052 .frp_sw_if_index = ~0,
6053 .frp_fib_index = 0,
6054 .frp_weight = 1,
6055 .frp_preference = 10,
6056 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6057 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6058 };
6059 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006060 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006061 .frp_sw_if_index = ~0,
6062 .frp_fib_index = 0,
6063 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006064 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006065 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6066 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6067 };
6068 fib_route_path_t *r_paths = NULL;
6069
6070 vec_add1(r_paths, r_path_hi);
6071 vec_add1(r_paths, r_path_low);
6072 vec_add1(r_paths, r_path_med);
6073
6074 /*
6075 * add many recursive so we get the LB MAp created
6076 */
Neale Ranns2303cb12018-02-21 04:57:17 -08006077#define N_PFXS 64
Neale Ranns57b58602017-07-15 07:37:25 -07006078 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006079 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006080 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6081 {
6082 pfx_r[n_pfxs].fp_len = 32;
6083 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6084 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6085 clib_host_to_net_u32(0x02000000 + n_pfxs);
6086
6087 fei = fib_table_entry_path_add2(0,
6088 &pfx_r[n_pfxs],
6089 FIB_SOURCE_API,
6090 FIB_ENTRY_FLAG_NONE,
6091 r_paths);
6092
Neale Ranns2303cb12018-02-21 04:57:17 -08006093 FIB_TEST(!fib_test_validate_entry(fei,
6094 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6095 1,
6096 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006097 "recursive via high preference paths");
6098
6099 /*
6100 * withdraw hig pref resolving entry
6101 */
6102 fib_table_entry_delete(0,
6103 &pfx_1_1_1_1_s_32,
6104 FIB_SOURCE_API);
6105
6106 /* suspend so the update walk kicks int */
6107 vlib_process_suspend(vlib_get_main(), 1e-5);
6108
Neale Ranns2303cb12018-02-21 04:57:17 -08006109 FIB_TEST(!fib_test_validate_entry(fei,
6110 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6111 1,
6112 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006113 "recursive via medium preference paths");
6114
6115 /*
6116 * withdraw medium pref resolving entry
6117 */
6118 fib_table_entry_delete(0,
6119 &pfx_1_1_1_2_s_32,
6120 FIB_SOURCE_API);
6121
6122 /* suspend so the update walk kicks int */
6123 vlib_process_suspend(vlib_get_main(), 1e-5);
6124
Neale Ranns2303cb12018-02-21 04:57:17 -08006125 FIB_TEST(!fib_test_validate_entry(fei,
6126 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6127 1,
6128 &ip_o_1_1_1_3),
Neale Ranns57b58602017-07-15 07:37:25 -07006129 "recursive via low preference paths");
6130
6131 /*
6132 * add back paths for next iteration
6133 */
6134 fei = fib_table_entry_update(0,
6135 &pfx_1_1_1_2_s_32,
6136 FIB_SOURCE_API,
6137 FIB_ENTRY_FLAG_NONE,
6138 nr_paths);
6139 fei = fib_table_entry_update(0,
6140 &pfx_1_1_1_1_s_32,
6141 FIB_SOURCE_API,
6142 FIB_ENTRY_FLAG_NONE,
6143 nr_paths);
6144
6145 /* suspend so the update walk kicks int */
6146 vlib_process_suspend(vlib_get_main(), 1e-5);
6147
6148 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
Neale Ranns2303cb12018-02-21 04:57:17 -08006149 FIB_TEST(!fib_test_validate_entry(fei,
6150 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6151 1,
6152 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006153 "recursive via high preference paths");
6154 }
6155
6156
6157 fib_table_entry_delete(0,
6158 &pfx_1_1_1_1_s_32,
6159 FIB_SOURCE_API);
6160
6161 /* suspend so the update walk kicks int */
6162 vlib_process_suspend(vlib_get_main(), 1e-5);
6163
6164 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6165 {
6166 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6167
Neale Ranns2303cb12018-02-21 04:57:17 -08006168 FIB_TEST(!fib_test_validate_entry(fei,
6169 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6170 1,
6171 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006172 "recursive via medium preference paths");
6173 }
6174 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6175 {
6176 fib_table_entry_delete(0,
6177 &pfx_r[n_pfxs],
6178 FIB_SOURCE_API);
6179 }
6180
6181 /*
6182 * Cleanup
6183 */
6184 fib_table_entry_delete(0,
6185 &pfx_1_1_1_2_s_32,
6186 FIB_SOURCE_API);
6187 fib_table_entry_delete(0,
6188 &pfx_1_1_1_3_s_32,
6189 FIB_SOURCE_API);
6190
6191 dpo_reset(&ip_1_1_1_1);
6192 dpo_reset(&ip_1_1_1_2);
6193 dpo_reset(&ip_1_1_1_3);
6194 adj_unlock(ai_low_2);
6195 adj_unlock(ai_low_1);
6196 adj_unlock(ai_med_2);
6197 adj_unlock(ai_med_1);
6198 adj_unlock(ai_hi_2);
6199 adj_unlock(ai_hi_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08006200
6201 return (res);
Neale Ranns57b58602017-07-15 07:37:25 -07006202}
Neale Rannsad422ed2016-11-02 14:20:04 +00006203
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006204/*
6205 * Test the recursive route route handling for GRE tunnels
6206 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006207static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006208fib_test_label (void)
6209{
6210 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;
6211 const u32 fib_index = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -08006212 int lb_count, ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006213 test_main_t *tm;
6214 ip4_main_t *im;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006215
Neale Ranns2303cb12018-02-21 04:57:17 -08006216 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006217 lb_count = pool_elts(load_balance_pool);
6218 tm = &test_main;
6219 im = &ip4_main;
6220
6221 /*
6222 * add interface routes. We'll assume this works. It's more rigorously
6223 * tested elsewhere.
6224 */
6225 fib_prefix_t local0_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006226 .fp_len = 24,
6227 .fp_proto = FIB_PROTOCOL_IP4,
6228 .fp_addr = {
6229 .ip4 = {
6230 /* 10.10.10.10 */
6231 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6232 },
6233 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006234 };
6235
6236 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08006237 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006238
6239 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6240 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6241
6242 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006243 FIB_SOURCE_INTERFACE,
6244 (FIB_ENTRY_FLAG_CONNECTED |
6245 FIB_ENTRY_FLAG_ATTACHED),
6246 DPO_PROTO_IP4,
6247 NULL,
6248 tm->hw[0]->sw_if_index,
6249 ~0,
6250 1,
6251 NULL,
6252 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006253 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6254 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006255 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006256
6257 local0_pfx.fp_len = 32;
6258 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006259 FIB_SOURCE_INTERFACE,
6260 (FIB_ENTRY_FLAG_CONNECTED |
6261 FIB_ENTRY_FLAG_LOCAL),
6262 DPO_PROTO_IP4,
6263 NULL,
6264 tm->hw[0]->sw_if_index,
6265 ~0, // invalid fib index
6266 1,
6267 NULL,
6268 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006269 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6270
6271 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006272 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006273
6274 fib_prefix_t local1_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006275 .fp_len = 24,
6276 .fp_proto = FIB_PROTOCOL_IP4,
6277 .fp_addr = {
6278 .ip4 = {
6279 /* 10.10.11.10 */
6280 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6281 },
6282 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006283 };
6284
6285 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6286 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6287
6288 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006289 FIB_SOURCE_INTERFACE,
6290 (FIB_ENTRY_FLAG_CONNECTED |
6291 FIB_ENTRY_FLAG_ATTACHED),
6292 DPO_PROTO_IP4,
6293 NULL,
6294 tm->hw[1]->sw_if_index,
6295 ~0,
6296 1,
6297 NULL,
6298 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006299 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6300 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006301 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006302
6303 local1_pfx.fp_len = 32;
6304 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006305 FIB_SOURCE_INTERFACE,
6306 (FIB_ENTRY_FLAG_CONNECTED |
6307 FIB_ENTRY_FLAG_LOCAL),
6308 DPO_PROTO_IP4,
6309 NULL,
6310 tm->hw[1]->sw_if_index,
6311 ~0, // invalid fib index
6312 1,
6313 NULL,
6314 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006315 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6316
6317 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006318 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006319
6320 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006321 .ip4 = {
6322 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6323 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006324 };
6325 ip46_address_t nh_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006326 .ip4 = {
6327 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6328 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006329 };
6330 ip46_address_t nh_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006331 .ip4 = {
6332 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6333 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006334 };
6335
6336 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006337 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006338 &nh_10_10_11_1,
6339 tm->hw[1]->sw_if_index);
6340 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006341 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006342 &nh_10_10_11_2,
6343 tm->hw[1]->sw_if_index);
6344 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006345 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006346 &nh_10_10_10_1,
6347 tm->hw[0]->sw_if_index);
6348 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006349 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006350 &nh_10_10_11_2,
6351 tm->hw[1]->sw_if_index);
6352 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006353 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006354 &nh_10_10_11_1,
6355 tm->hw[1]->sw_if_index);
6356
6357 /*
6358 * Add an etry with one path with a real out-going label
6359 */
6360 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006361 .fp_len = 32,
6362 .fp_proto = FIB_PROTOCOL_IP4,
6363 .fp_addr = {
6364 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6365 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006366 };
6367 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006368 .type = FT_LB_LABEL_O_ADJ,
6369 .label_o_adj = {
6370 .adj = ai_mpls_10_10_10_1,
6371 .label = 99,
6372 .eos = MPLS_EOS,
6373 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006374 };
6375 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006376 .type = FT_LB_LABEL_O_ADJ,
6377 .label_o_adj = {
6378 .adj = ai_mpls_10_10_10_1,
6379 .label = 99,
6380 .eos = MPLS_NON_EOS,
6381 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006382 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006383 fib_mpls_label_t *l99 = NULL, fml99 = {
6384 .fml_value = 99,
6385 };
6386 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006387
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006388 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006389 &pfx_1_1_1_1_s_32,
6390 FIB_SOURCE_API,
6391 FIB_ENTRY_FLAG_NONE,
6392 DPO_PROTO_IP4,
6393 &nh_10_10_10_1,
6394 tm->hw[0]->sw_if_index,
6395 ~0, // invalid fib index
6396 1,
6397 l99,
6398 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006399
6400 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6401 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6402
Neale Ranns2303cb12018-02-21 04:57:17 -08006403 FIB_TEST(!fib_test_validate_entry(fei,
6404 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6405 1,
6406 &l99_eos_o_10_10_10_1),
6407 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006408
6409 /*
6410 * add a path with an implicit NULL label
6411 */
6412 fib_test_lb_bucket_t a_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006413 .type = FT_LB_ADJ,
6414 .adj = {
6415 .adj = ai_v4_10_10_11_1,
6416 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006417 };
6418 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006419 .type = FT_LB_ADJ,
6420 .adj = {
6421 .adj = ai_mpls_10_10_11_1,
6422 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006423 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006424 fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = {
6425 .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
6426 };
6427 vec_add1(l_imp_null, fml_imp_null);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006428
6429 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006430 &pfx_1_1_1_1_s_32,
6431 FIB_SOURCE_API,
6432 FIB_ENTRY_FLAG_NONE,
6433 DPO_PROTO_IP4,
6434 &nh_10_10_11_1,
6435 tm->hw[1]->sw_if_index,
6436 ~0, // invalid fib index
6437 1,
6438 l_imp_null,
6439 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006440
Neale Ranns2303cb12018-02-21 04:57:17 -08006441 FIB_TEST(!fib_test_validate_entry(fei,
6442 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6443 2,
6444 &l99_eos_o_10_10_10_1,
6445 &a_o_10_10_11_1),
6446 "1.1.1.1/32 LB 2 buckets via: "
6447 "label 99 over 10.10.10.1, "
6448 "adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006449
6450 /*
6451 * assign the route a local label
6452 */
6453 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006454 &pfx_1_1_1_1_s_32,
6455 24001);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006456
6457 fib_prefix_t pfx_24001_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006458 .fp_proto = FIB_PROTOCOL_MPLS,
6459 .fp_label = 24001,
6460 .fp_eos = MPLS_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006461 };
6462 fib_prefix_t pfx_24001_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006463 .fp_proto = FIB_PROTOCOL_MPLS,
6464 .fp_label = 24001,
6465 .fp_eos = MPLS_NON_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006466 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006467 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006468 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006469 .adj = {
6470 .adj = ai_v4_10_10_11_1,
6471 },
6472 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006473
6474 /*
6475 * The EOS entry should link to both the paths,
6476 * and use an ip adj for the imp-null
6477 * The NON-EOS entry should link to both the paths,
6478 * and use an mpls adj for the imp-null
6479 */
6480 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006481 &pfx_24001_eos);
6482 FIB_TEST(!fib_test_validate_entry(fei,
6483 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6484 2,
6485 &l99_eos_o_10_10_10_1,
6486 &disp_o_10_10_11_1),
6487 "24001/eos LB 2 buckets via: "
6488 "label 99 over 10.10.10.1, "
6489 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006490
6491
6492 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006493 &pfx_24001_neos);
6494 FIB_TEST(!fib_test_validate_entry(fei,
6495 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6496 2,
6497 &l99_neos_o_10_10_10_1,
6498 &a_mpls_o_10_10_11_1),
6499 "24001/neos LB 1 bucket via: "
6500 "label 99 over 10.10.10.1 ",
6501 "mpls-adj via 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006502
6503 /*
6504 * add an unlabelled path, this is excluded from the neos chains,
6505 */
6506 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006507 .type = FT_LB_ADJ,
6508 .adj = {
6509 .adj = ai_v4_10_10_11_2,
6510 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006511 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006512 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006513 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006514 .adj = {
6515 .adj = ai_v4_10_10_11_2,
6516 },
6517 };
6518
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006519
6520 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006521 &pfx_1_1_1_1_s_32,
6522 FIB_SOURCE_API,
6523 FIB_ENTRY_FLAG_NONE,
6524 DPO_PROTO_IP4,
6525 &nh_10_10_11_2,
6526 tm->hw[1]->sw_if_index,
6527 ~0, // invalid fib index
6528 1,
6529 NULL,
6530 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006531
Neale Ranns2303cb12018-02-21 04:57:17 -08006532 FIB_TEST(!fib_test_validate_entry(fei,
6533 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6534 16, // 3 choices spread over 16 buckets
6535 &l99_eos_o_10_10_10_1,
6536 &l99_eos_o_10_10_10_1,
6537 &l99_eos_o_10_10_10_1,
6538 &l99_eos_o_10_10_10_1,
6539 &l99_eos_o_10_10_10_1,
6540 &l99_eos_o_10_10_10_1,
6541 &a_o_10_10_11_1,
6542 &a_o_10_10_11_1,
6543 &a_o_10_10_11_1,
6544 &a_o_10_10_11_1,
6545 &a_o_10_10_11_1,
6546 &adj_o_10_10_11_2,
6547 &adj_o_10_10_11_2,
6548 &adj_o_10_10_11_2,
6549 &adj_o_10_10_11_2,
6550 &adj_o_10_10_11_2),
6551 "1.1.1.1/32 LB 16 buckets via: "
6552 "label 99 over 10.10.10.1, "
6553 "adj over 10.10.11.1",
6554 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006555
6556 /*
6557 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6558 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006559 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006560 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006561 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6562 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006563
6564 /*
6565 * n-eos has only the 2 labelled paths
6566 */
6567 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006568 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006569
Neale Ranns2303cb12018-02-21 04:57:17 -08006570 FIB_TEST(!fib_test_validate_entry(fei,
6571 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6572 2,
6573 &l99_neos_o_10_10_10_1,
6574 &a_mpls_o_10_10_11_1),
6575 "24001/neos LB 2 buckets via: "
6576 "label 99 over 10.10.10.1, "
6577 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006578
6579 /*
6580 * A labelled recursive
6581 */
6582 fib_prefix_t pfx_2_2_2_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006583 .fp_len = 32,
6584 .fp_proto = FIB_PROTOCOL_IP4,
6585 .fp_addr = {
6586 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6587 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006588 };
6589 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6590 .type = FT_LB_LABEL_O_LB,
6591 .label_o_lb = {
6592 .lb = non_eos_1_1_1_1.dpoi_index,
6593 .label = 1600,
6594 .eos = MPLS_EOS,
Neale Ranns31ed7442018-02-23 05:29:09 -08006595 .mode = FIB_MPLS_LSP_MODE_UNIFORM,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006596 },
6597 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006598 fib_mpls_label_t *l1600 = NULL, fml1600 = {
6599 .fml_value = 1600,
6600 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
6601 };
6602 vec_add1(l1600, fml1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006603
Neale Ranns31ed7442018-02-23 05:29:09 -08006604 fei = fib_table_entry_update_one_path(fib_index,
6605 &pfx_2_2_2_2_s_32,
6606 FIB_SOURCE_API,
6607 FIB_ENTRY_FLAG_NONE,
6608 DPO_PROTO_IP4,
6609 &pfx_1_1_1_1_s_32.fp_addr,
6610 ~0,
6611 fib_index,
6612 1,
6613 l1600,
6614 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006615
Neale Ranns2303cb12018-02-21 04:57:17 -08006616 FIB_TEST(!fib_test_validate_entry(fei,
6617 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6618 1,
6619 &l1600_eos_o_1_1_1_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006620 "2.2.2.2.2/32 LB 1 buckets via: "
6621 "label 1600 over 1.1.1.1");
6622
Neale Ranns948e00f2016-10-20 13:39:34 +01006623 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006624 index_t urpfi;
6625
6626 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6627 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6628
6629 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006630 "uRPF check for 2.2.2.2/32 on %d OK",
6631 tm->hw[0]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006632 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006633 "uRPF check for 2.2.2.2/32 on %d OK",
6634 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006635 FIB_TEST(!fib_urpf_check(urpfi, 99),
Neale Ranns2303cb12018-02-21 04:57:17 -08006636 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6637 99);
Neale Ranns3ee44042016-10-03 13:05:48 +01006638
6639 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6640 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006641 "Shared uRPF on IP and non-EOS chain");
Neale Ranns3ee44042016-10-03 13:05:48 +01006642
6643 dpo_reset(&dpo_44);
6644
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006645 /*
6646 * we are holding a lock on the non-eos LB of the via-entry.
6647 * do a PIC-core failover by shutting the link of the via-entry.
6648 *
6649 * shut down the link with the valid label
6650 */
6651 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006652 tm->hw[0]->sw_if_index,
6653 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006654
6655 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006656 FIB_TEST(!fib_test_validate_entry(fei,
6657 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6658 2,
6659 &a_o_10_10_11_1,
6660 &adj_o_10_10_11_2),
6661 "1.1.1.1/32 LB 2 buckets via: "
6662 "adj over 10.10.11.1, ",
6663 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006664
6665 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006666 &pfx_24001_eos);
6667 FIB_TEST(!fib_test_validate_entry(fei,
6668 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6669 2,
6670 &disp_o_10_10_11_1,
6671 &disp_o_10_10_11_2),
6672 "24001/eos LB 2 buckets via: "
6673 "mpls-disp adj over 10.10.11.1, ",
6674 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006675
6676 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006677 &pfx_24001_neos);
6678 FIB_TEST(!fib_test_validate_entry(fei,
6679 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6680 1,
6681 &a_mpls_o_10_10_11_1),
6682 "24001/neos LB 1 buckets via: "
6683 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006684
6685 /*
6686 * test that the pre-failover load-balance has been in-place
6687 * modified
6688 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006689 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006690 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006691 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6692 &current);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006693
6694 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6695 &current),
Neale Ranns2303cb12018-02-21 04:57:17 -08006696 "PIC-core LB inplace modified %U %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006697 format_dpo_id, &non_eos_1_1_1_1, 0,
6698 format_dpo_id, &current, 0);
6699
6700 dpo_reset(&non_eos_1_1_1_1);
6701 dpo_reset(&current);
6702
6703 /*
6704 * no-shut the link with the valid label
6705 */
6706 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006707 tm->hw[0]->sw_if_index,
6708 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006709
6710 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006711 FIB_TEST(!fib_test_validate_entry(fei,
6712 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6713 16, // 3 choices spread over 16 buckets
6714 &l99_eos_o_10_10_10_1,
6715 &l99_eos_o_10_10_10_1,
6716 &l99_eos_o_10_10_10_1,
6717 &l99_eos_o_10_10_10_1,
6718 &l99_eos_o_10_10_10_1,
6719 &l99_eos_o_10_10_10_1,
6720 &a_o_10_10_11_1,
6721 &a_o_10_10_11_1,
6722 &a_o_10_10_11_1,
6723 &a_o_10_10_11_1,
6724 &a_o_10_10_11_1,
6725 &adj_o_10_10_11_2,
6726 &adj_o_10_10_11_2,
6727 &adj_o_10_10_11_2,
6728 &adj_o_10_10_11_2,
6729 &adj_o_10_10_11_2),
6730 "1.1.1.1/32 LB 16 buckets via: "
6731 "label 99 over 10.10.10.1, "
6732 "adj over 10.10.11.1",
6733 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006734
6735
6736 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006737 &pfx_24001_eos);
6738 FIB_TEST(!fib_test_validate_entry(fei,
6739 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6740 16, // 3 choices spread over 16 buckets
6741 &l99_eos_o_10_10_10_1,
6742 &l99_eos_o_10_10_10_1,
6743 &l99_eos_o_10_10_10_1,
6744 &l99_eos_o_10_10_10_1,
6745 &l99_eos_o_10_10_10_1,
6746 &l99_eos_o_10_10_10_1,
6747 &disp_o_10_10_11_1,
6748 &disp_o_10_10_11_1,
6749 &disp_o_10_10_11_1,
6750 &disp_o_10_10_11_1,
6751 &disp_o_10_10_11_1,
6752 &disp_o_10_10_11_2,
6753 &disp_o_10_10_11_2,
6754 &disp_o_10_10_11_2,
6755 &disp_o_10_10_11_2,
6756 &disp_o_10_10_11_2),
6757 "24001/eos LB 16 buckets via: "
6758 "label 99 over 10.10.10.1, "
6759 "MPLS disp adj over 10.10.11.1",
6760 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006761
6762 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006763 &pfx_24001_neos);
6764 FIB_TEST(!fib_test_validate_entry(fei,
6765 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6766 2,
6767 &l99_neos_o_10_10_10_1,
6768 &a_mpls_o_10_10_11_1),
6769 "24001/neos LB 2 buckets via: "
6770 "label 99 over 10.10.10.1, "
6771 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006772
6773 /*
6774 * remove the first path with the valid label
6775 */
6776 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006777 &pfx_1_1_1_1_s_32,
6778 FIB_SOURCE_API,
6779 DPO_PROTO_IP4,
6780 &nh_10_10_10_1,
6781 tm->hw[0]->sw_if_index,
6782 ~0, // invalid fib index
6783 1,
6784 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006785
6786 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006787 FIB_TEST(!fib_test_validate_entry(fei,
6788 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6789 2,
6790 &a_o_10_10_11_1,
6791 &adj_o_10_10_11_2),
6792 "1.1.1.1/32 LB 2 buckets via: "
6793 "adj over 10.10.11.1, "
6794 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006795
6796 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006797 &pfx_24001_eos);
6798 FIB_TEST(!fib_test_validate_entry(fei,
6799 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6800 2,
6801 &disp_o_10_10_11_1,
6802 &disp_o_10_10_11_2),
6803 "24001/eos LB 2 buckets via: "
6804 "MPLS disp adj over 10.10.11.1, "
6805 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006806
6807 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006808 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006809
Neale Ranns2303cb12018-02-21 04:57:17 -08006810 FIB_TEST(!fib_test_validate_entry(fei,
6811 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6812 1,
6813 &a_mpls_o_10_10_11_1),
6814 "24001/neos LB 1 buckets via: "
6815 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006816
6817 /*
6818 * remove the other path with a valid label
6819 */
6820 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006821 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006822 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006823 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006824 .type = FT_LB_DROP,
6825 .special = {
6826 .adj = DPO_PROTO_MPLS,
6827 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07006828 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006829
6830 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006831 &pfx_1_1_1_1_s_32,
6832 FIB_SOURCE_API,
6833 DPO_PROTO_IP4,
6834 &nh_10_10_11_1,
6835 tm->hw[1]->sw_if_index,
6836 ~0, // invalid fib index
6837 1,
6838 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006839
6840 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006841 FIB_TEST(!fib_test_validate_entry(fei,
6842 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6843 1,
6844 &adj_o_10_10_11_2),
6845 "1.1.1.1/32 LB 1 buckets via: "
6846 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006847
6848 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006849 &pfx_24001_eos);
6850 FIB_TEST(!fib_test_validate_entry(fei,
6851 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6852 1,
6853 &disp_o_10_10_11_2),
6854 "24001/eos LB 1 buckets via: "
6855 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006856
6857 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006858 &pfx_24001_neos);
6859 FIB_TEST(!fib_test_validate_entry(fei,
6860 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6861 1,
6862 &mpls_bucket_drop),
6863 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006864
6865 /*
6866 * add back the path with the valid label
6867 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006868 l99 = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08006869 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006870
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006871 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006872 &pfx_1_1_1_1_s_32,
6873 FIB_SOURCE_API,
6874 FIB_ENTRY_FLAG_NONE,
6875 DPO_PROTO_IP4,
6876 &nh_10_10_10_1,
6877 tm->hw[0]->sw_if_index,
6878 ~0, // invalid fib index
6879 1,
6880 l99,
6881 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006882
6883 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006884 FIB_TEST(!fib_test_validate_entry(fei,
6885 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6886 2,
6887 &l99_eos_o_10_10_10_1,
6888 &adj_o_10_10_11_2),
6889 "1.1.1.1/32 LB 2 buckets via: "
6890 "label 99 over 10.10.10.1, "
6891 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006892
6893 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006894 &pfx_24001_eos);
6895 FIB_TEST(!fib_test_validate_entry(fei,
6896 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6897 2,
6898 &l99_eos_o_10_10_10_1,
6899 &disp_o_10_10_11_2),
6900 "24001/eos LB 2 buckets via: "
6901 "label 99 over 10.10.10.1, "
6902 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006903
6904 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006905 &pfx_24001_neos);
6906 FIB_TEST(!fib_test_validate_entry(fei,
6907 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6908 1,
6909 &l99_neos_o_10_10_10_1),
6910 "24001/neos LB 1 buckets via: "
6911 "label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006912
6913 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006914 * change the local label
6915 */
6916 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006917 &pfx_1_1_1_1_s_32,
6918 25005);
Neale Ranns1357f3b2016-10-16 12:01:42 -07006919
6920 fib_prefix_t pfx_25005_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006921 .fp_proto = FIB_PROTOCOL_MPLS,
6922 .fp_label = 25005,
6923 .fp_eos = MPLS_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006924 };
6925 fib_prefix_t pfx_25005_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006926 .fp_proto = FIB_PROTOCOL_MPLS,
6927 .fp_label = 25005,
6928 .fp_eos = MPLS_NON_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006929 };
6930
6931 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006932 fib_table_lookup(fib_index, &pfx_24001_eos)),
6933 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006934 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006935 fib_table_lookup(fib_index, &pfx_24001_neos)),
6936 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006937
6938 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006939 &pfx_25005_eos);
6940 FIB_TEST(!fib_test_validate_entry(fei,
6941 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6942 2,
6943 &l99_eos_o_10_10_10_1,
6944 &disp_o_10_10_11_2),
6945 "25005/eos LB 2 buckets via: "
6946 "label 99 over 10.10.10.1, "
6947 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006948
6949 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006950 &pfx_25005_neos);
6951 FIB_TEST(!fib_test_validate_entry(fei,
6952 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6953 1,
6954 &l99_neos_o_10_10_10_1),
6955 "25005/neos LB 1 buckets via: "
6956 "label 99 over 10.10.10.1");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006957
6958 /*
6959 * remove the local label.
6960 * the check that the MPLS entries are gone is done by the fact the
6961 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006962 */
6963 fib_table_entry_local_label_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006964 &pfx_1_1_1_1_s_32,
6965 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006966
6967 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006968 FIB_TEST(!fib_test_validate_entry(fei,
6969 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6970 2,
6971 &l99_eos_o_10_10_10_1,
6972 &adj_o_10_10_11_2),
6973 "24001/eos LB 2 buckets via: "
6974 "label 99 over 10.10.10.1, "
6975 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006976
6977 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006978 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6979 "No more MPLS FIB entries => table removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006980
6981 /*
6982 * add another via-entry for the recursive
6983 */
6984 fib_prefix_t pfx_1_1_1_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006985 .fp_len = 32,
6986 .fp_proto = FIB_PROTOCOL_IP4,
6987 .fp_addr = {
6988 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6989 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006990 };
6991 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006992 .type = FT_LB_LABEL_O_ADJ,
6993 .label_o_adj = {
6994 .adj = ai_mpls_10_10_10_1,
6995 .label = 101,
6996 .eos = MPLS_EOS,
6997 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006998 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006999 fib_mpls_label_t *l101 = NULL, fml101 = {
7000 .fml_value = 101,
7001 };
7002 vec_add1(l101, fml101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007003
7004 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007005 &pfx_1_1_1_2_s_32,
7006 FIB_SOURCE_API,
7007 FIB_ENTRY_FLAG_NONE,
7008 DPO_PROTO_IP4,
7009 &nh_10_10_10_1,
7010 tm->hw[0]->sw_if_index,
7011 ~0, // invalid fib index
7012 1,
7013 l101,
7014 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007015
Neale Ranns2303cb12018-02-21 04:57:17 -08007016 FIB_TEST(!fib_test_validate_entry(fei,
7017 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7018 1,
7019 &l101_eos_o_10_10_10_1),
7020 "1.1.1.2/32 LB 1 buckets via: "
7021 "label 101 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007022
Neale Ranns948e00f2016-10-20 13:39:34 +01007023 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007024 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007025 &pfx_1_1_1_1_s_32),
7026 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7027 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007028 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007029 &pfx_1_1_1_2_s_32),
7030 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7031 &non_eos_1_1_1_2);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007032
7033 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007034 .type = FT_LB_LABEL_O_LB,
7035 .label_o_lb = {
7036 .lb = non_eos_1_1_1_2.dpoi_index,
7037 .label = 1601,
7038 .eos = MPLS_EOS,
7039 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007040 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007041 fib_mpls_label_t *l1601 = NULL, fml1601 = {
7042 .fml_value = 1601,
7043 };
7044 vec_add1(l1601, fml1601);
Neale Rannsad422ed2016-11-02 14:20:04 +00007045
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007046 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
7047
7048 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007049 &pfx_2_2_2_2_s_32,
7050 FIB_SOURCE_API,
7051 FIB_ENTRY_FLAG_NONE,
7052 DPO_PROTO_IP4,
7053 &pfx_1_1_1_2_s_32.fp_addr,
7054 ~0,
7055 fib_index,
7056 1,
7057 l1601,
7058 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007059
Neale Ranns2303cb12018-02-21 04:57:17 -08007060 FIB_TEST(!fib_test_validate_entry(fei,
7061 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7062 2,
7063 &l1600_eos_o_1_1_1_1,
7064 &l1601_eos_o_1_1_1_2),
7065 "2.2.2.2/32 LB 2 buckets via: "
7066 "label 1600 via 1.1,1.1, "
7067 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007068
7069 /*
7070 * update the via-entry so it no longer has an imp-null path.
7071 * the LB for the recursive can use an imp-null
7072 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007073 l_imp_null = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007074 vec_add1(l_imp_null, fml_imp_null);
Neale Rannsad422ed2016-11-02 14:20:04 +00007075
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007076 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007077 &pfx_1_1_1_2_s_32,
7078 FIB_SOURCE_API,
7079 FIB_ENTRY_FLAG_NONE,
7080 DPO_PROTO_IP4,
7081 &nh_10_10_11_1,
7082 tm->hw[1]->sw_if_index,
7083 ~0, // invalid fib index
7084 1,
7085 l_imp_null,
7086 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007087
Neale Ranns2303cb12018-02-21 04:57:17 -08007088 FIB_TEST(!fib_test_validate_entry(fei,
7089 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7090 1,
7091 &a_o_10_10_11_1),
7092 "1.1.1.2/32 LB 1 buckets via: "
7093 "adj 10.10.11.1");
7094
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007095 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007096 FIB_TEST(!fib_test_validate_entry(fei,
7097 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7098 2,
7099 &l1600_eos_o_1_1_1_1,
7100 &l1601_eos_o_1_1_1_2),
7101 "2.2.2.2/32 LB 2 buckets via: "
7102 "label 1600 via 1.1,1.1, "
7103 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007104
7105 /*
7106 * update the via-entry so it no longer has labelled paths.
7107 * the LB for the recursive should exclue this via form its LB
7108 */
7109 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007110 &pfx_1_1_1_2_s_32,
7111 FIB_SOURCE_API,
7112 FIB_ENTRY_FLAG_NONE,
7113 DPO_PROTO_IP4,
7114 &nh_10_10_11_1,
7115 tm->hw[1]->sw_if_index,
7116 ~0, // invalid fib index
7117 1,
7118 NULL,
7119 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007120
Neale Ranns2303cb12018-02-21 04:57:17 -08007121 FIB_TEST(!fib_test_validate_entry(fei,
7122 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7123 1,
7124 &a_o_10_10_11_1),
7125 "1.1.1.2/32 LB 1 buckets via: "
7126 "adj 10.10.11.1");
7127
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007128 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007129 FIB_TEST(!fib_test_validate_entry(fei,
7130 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7131 1,
7132 &l1600_eos_o_1_1_1_1),
7133 "2.2.2.2/32 LB 1 buckets via: "
7134 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007135
7136 dpo_reset(&non_eos_1_1_1_1);
7137 dpo_reset(&non_eos_1_1_1_2);
7138
7139 /*
7140 * Add a recursive with no out-labels. We expect to use the IP of the via
7141 */
7142 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007143 .fp_len = 32,
7144 .fp_proto = FIB_PROTOCOL_IP4,
7145 .fp_addr = {
7146 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7147 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007148 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007149 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007150
7151 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007152 &pfx_2_2_2_3_s_32,
7153 FIB_SOURCE_API,
7154 FIB_ENTRY_FLAG_NONE,
7155 DPO_PROTO_IP4,
7156 &pfx_1_1_1_1_s_32.fp_addr,
7157 ~0,
7158 fib_index,
7159 1,
7160 NULL,
7161 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007162
7163 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007164 &pfx_1_1_1_1_s_32),
7165 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7166 &ip_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007167
7168 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007169 .type = FT_LB_O_LB,
7170 .lb = {
7171 .lb = ip_1_1_1_1.dpoi_index,
7172 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007173 };
7174
7175 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007176 FIB_TEST(!fib_test_validate_entry(fei,
7177 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7178 1,
7179 &ip_o_1_1_1_1),
7180 "2.2.2.2.3/32 LB 1 buckets via: "
7181 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007182
7183 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08007184 * Add a recursive with an imp-null out-label.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007185 * We expect to use the IP of the via
7186 */
7187 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007188 .fp_len = 32,
7189 .fp_proto = FIB_PROTOCOL_IP4,
7190 .fp_addr = {
7191 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7192 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007193 };
7194
7195 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007196 &pfx_2_2_2_4_s_32,
7197 FIB_SOURCE_API,
7198 FIB_ENTRY_FLAG_NONE,
7199 DPO_PROTO_IP4,
7200 &pfx_1_1_1_1_s_32.fp_addr,
7201 ~0,
7202 fib_index,
7203 1,
7204 NULL,
7205 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007206
7207 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007208 FIB_TEST(!fib_test_validate_entry(fei,
7209 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7210 1,
7211 &ip_o_1_1_1_1),
7212 "2.2.2.2.4/32 LB 1 buckets via: "
7213 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007214
7215 dpo_reset(&ip_1_1_1_1);
7216
7217 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007218 * Create an entry with a deep label stack
7219 */
7220 fib_prefix_t pfx_2_2_5_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007221 .fp_len = 32,
7222 .fp_proto = FIB_PROTOCOL_IP4,
7223 .fp_addr = {
7224 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7225 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007226 };
7227 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007228 .type = FT_LB_LABEL_STACK_O_ADJ,
7229 .label_stack_o_adj = {
7230 .adj = ai_mpls_10_10_11_1,
7231 .label_stack_size = 8,
7232 .label_stack = {
7233 200, 201, 202, 203, 204, 205, 206, 207
7234 },
7235 .eos = MPLS_EOS,
7236 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007237 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007238 fib_mpls_label_t *label_stack = NULL;
Neale Rannsad422ed2016-11-02 14:20:04 +00007239 vec_validate(label_stack, 7);
7240 for (ii = 0; ii < 8; ii++)
7241 {
Neale Ranns31ed7442018-02-23 05:29:09 -08007242 label_stack[ii].fml_value = ii + 200;
Neale Rannsad422ed2016-11-02 14:20:04 +00007243 }
7244
7245 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007246 &pfx_2_2_5_5_s_32,
7247 FIB_SOURCE_API,
7248 FIB_ENTRY_FLAG_NONE,
7249 DPO_PROTO_IP4,
7250 &nh_10_10_11_1,
7251 tm->hw[1]->sw_if_index,
7252 ~0, // invalid fib index
7253 1,
7254 label_stack,
7255 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00007256
Neale Ranns2303cb12018-02-21 04:57:17 -08007257 FIB_TEST(!fib_test_validate_entry(fei,
7258 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7259 1,
7260 &ls_eos_o_10_10_10_1),
7261 "2.2.5.5/32 LB 1 buckets via: "
7262 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00007263 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7264
7265 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007266 * cleanup
7267 */
7268 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007269 &pfx_1_1_1_2_s_32,
7270 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007271
7272 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007273 FIB_TEST(!fib_test_validate_entry(fei,
7274 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7275 1,
7276 &l1600_eos_o_1_1_1_1),
7277 "2.2.2.2/32 LB 1 buckets via: "
7278 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007279
7280 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007281 &pfx_1_1_1_1_s_32,
7282 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007283
Neale Ranns2303cb12018-02-21 04:57:17 -08007284 FIB_TEST(!fib_test_validate_entry(fei,
7285 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7286 1,
7287 &bucket_drop),
7288 "2.2.2.2/32 LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007289
7290 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007291 &pfx_2_2_2_2_s_32,
7292 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007293 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007294 &pfx_2_2_2_3_s_32,
7295 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007296 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007297 &pfx_2_2_2_4_s_32,
7298 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007299
7300 adj_unlock(ai_mpls_10_10_10_1);
7301 adj_unlock(ai_mpls_10_10_11_2);
7302 adj_unlock(ai_v4_10_10_11_1);
7303 adj_unlock(ai_v4_10_10_11_2);
7304 adj_unlock(ai_mpls_10_10_11_1);
7305
7306 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08007307 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007308
7309 local0_pfx.fp_len = 32;
7310 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007311 &local0_pfx,
7312 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007313 local0_pfx.fp_len = 24;
7314 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007315 &local0_pfx,
7316 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007317 local1_pfx.fp_len = 32;
7318 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007319 &local1_pfx,
7320 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007321 local1_pfx.fp_len = 24;
7322 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007323 &local1_pfx,
7324 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007325
7326 /*
7327 * +1 for the drop LB in the MPLS tables.
7328 */
7329 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08007330 "Load-balance resources freed %d of %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007331 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007332
Neale Ranns2303cb12018-02-21 04:57:17 -08007333 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007334}
7335
7336#define N_TEST_CHILDREN 4
7337#define PARENT_INDEX 0
7338
7339typedef struct fib_node_test_t_
7340{
7341 fib_node_t node;
7342 u32 sibling;
7343 u32 index;
7344 fib_node_back_walk_ctx_t *ctxs;
7345 u32 destroyed;
7346} fib_node_test_t;
7347
7348static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7349
7350#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7351
Neale Ranns2303cb12018-02-21 04:57:17 -08007352#define FOR_EACH_TEST_CHILD(_tc) \
7353 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7354 ii < N_TEST_CHILDREN+1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007355 ii++, (_tc) = &fib_test_nodes[ii])
7356
7357static fib_node_t *
7358fib_test_child_get_node (fib_node_index_t index)
7359{
7360 return (&fib_test_nodes[index].node);
7361}
7362
7363static int fib_test_walk_spawns_walks;
7364
7365static fib_node_back_walk_rc_t
7366fib_test_child_back_walk_notify (fib_node_t *node,
7367 fib_node_back_walk_ctx_t *ctx)
7368{
7369 fib_node_test_t *tc = (fib_node_test_t*) node;
7370
7371 vec_add1(tc->ctxs, *ctx);
7372
7373 if (1 == fib_test_walk_spawns_walks)
7374 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7375 if (2 == fib_test_walk_spawns_walks)
7376 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7377 FIB_WALK_PRIORITY_HIGH, ctx);
7378
7379 return (FIB_NODE_BACK_WALK_CONTINUE);
7380}
7381
7382static void
7383fib_test_child_last_lock_gone (fib_node_t *node)
7384{
7385 fib_node_test_t *tc = (fib_node_test_t *)node;
7386
7387 tc->destroyed = 1;
7388}
7389
7390/**
7391 * The FIB walk's graph node virtual function table
7392 */
7393static const fib_node_vft_t fib_test_child_vft = {
7394 .fnv_get = fib_test_child_get_node,
7395 .fnv_last_lock = fib_test_child_last_lock_gone,
7396 .fnv_back_walk = fib_test_child_back_walk_notify,
7397};
7398
7399/*
7400 * the function (that should have been static but isn't so I can do this)
7401 * that processes the walk from the async queue,
7402 */
7403f64 fib_walk_process_queues(vlib_main_t * vm,
7404 const f64 quota);
7405u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7406
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007407static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007408fib_test_walk (void)
7409{
7410 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7411 fib_node_test_t *tc;
7412 vlib_main_t *vm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007413 u32 ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007414
Neale Ranns2303cb12018-02-21 04:57:17 -08007415 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007416 vm = vlib_get_main();
7417 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7418
7419 /*
7420 * init a fake node on which we will add children
7421 */
7422 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7423 FIB_NODE_TYPE_TEST);
7424
7425 FOR_EACH_TEST_CHILD(tc)
7426 {
7427 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7428 fib_node_lock(&tc->node);
7429 tc->ctxs = NULL;
7430 tc->index = ii;
7431 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7432 PARENT_INDEX,
7433 FIB_NODE_TYPE_TEST, ii);
7434 }
7435
7436 /*
7437 * enqueue a walk across the parents children.
7438 */
Neale Ranns450cd302016-11-09 17:49:42 +00007439 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007440
7441 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7442 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7443 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7444 "Parent has %d children pre-walk",
7445 fib_node_list_get_size(PARENT()->fn_children));
7446
7447 /*
7448 * give the walk a large amount of time so it gets to the end
7449 */
7450 fib_walk_process_queues(vm, 1);
7451
7452 FOR_EACH_TEST_CHILD(tc)
7453 {
7454 FIB_TEST(1 == vec_len(tc->ctxs),
7455 "%d child visitsed %d times",
7456 ii, vec_len(tc->ctxs));
7457 vec_free(tc->ctxs);
7458 }
7459 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7460 "Queue is empty post walk");
7461 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7462 "Parent has %d children post walk",
7463 fib_node_list_get_size(PARENT()->fn_children));
7464
7465 /*
7466 * walk again. should be no increase in the number of visits, since
7467 * the walk will have terminated.
7468 */
7469 fib_walk_process_queues(vm, 1);
7470
7471 FOR_EACH_TEST_CHILD(tc)
7472 {
7473 FIB_TEST(0 == vec_len(tc->ctxs),
7474 "%d child visitsed %d times",
7475 ii, vec_len(tc->ctxs));
7476 }
7477
7478 /*
7479 * schedule a low and hig priority walk. expect the high to be performed
7480 * before the low.
7481 * schedule the high prio walk first so that it is further from the head
7482 * of the dependency list. that way it won't merge with the low one.
7483 */
7484 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7485 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7486
7487 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7488 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7489 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7490 FIB_WALK_PRIORITY_LOW, &low_ctx);
7491
7492 fib_walk_process_queues(vm, 1);
7493
7494 FOR_EACH_TEST_CHILD(tc)
7495 {
7496 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7497 "%d child visitsed by high prio walk", ii);
7498 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7499 "%d child visitsed by low prio walk", ii);
7500 vec_free(tc->ctxs);
7501 }
7502 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7503 "Queue is empty post prio walk");
7504 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7505 "Parent has %d children post prio walk",
7506 fib_node_list_get_size(PARENT()->fn_children));
7507
7508 /*
7509 * schedule 2 walks of the same priority that can be megred.
7510 * expect that each child is thus visited only once.
7511 */
7512 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7513 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7514
7515 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7516 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7517 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7518 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7519
7520 fib_walk_process_queues(vm, 1);
7521
7522 FOR_EACH_TEST_CHILD(tc)
7523 {
7524 FIB_TEST(1 == vec_len(tc->ctxs),
7525 "%d child visitsed %d times during merge walk",
7526 ii, vec_len(tc->ctxs));
7527 vec_free(tc->ctxs);
7528 }
7529 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7530 "Queue is empty post merge walk");
7531 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7532 "Parent has %d children post merge walk",
7533 fib_node_list_get_size(PARENT()->fn_children));
7534
7535 /*
7536 * schedule 2 walks of the same priority that cannot be megred.
7537 * expect that each child is thus visited twice and in the order
7538 * in which the walks were scheduled.
7539 */
7540 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7541 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7542
7543 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7544 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7545 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7546 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7547
7548 fib_walk_process_queues(vm, 1);
7549
7550 FOR_EACH_TEST_CHILD(tc)
7551 {
7552 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7553 "%d child visitsed by high prio walk", ii);
7554 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7555 "%d child visitsed by low prio walk", ii);
7556 vec_free(tc->ctxs);
7557 }
7558 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7559 "Queue is empty post no-merge walk");
7560 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7561 "Parent has %d children post no-merge walk",
7562 fib_node_list_get_size(PARENT()->fn_children));
7563
7564 /*
7565 * schedule a walk that makes one one child progress.
7566 * we do this by giving the queue draining process zero
7567 * time quanta. it's a do..while loop, so it does something.
7568 */
Neale Ranns450cd302016-11-09 17:49:42 +00007569 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007570
7571 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7572 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7573 fib_walk_process_queues(vm, 0);
7574
7575 FOR_EACH_TEST_CHILD(tc)
7576 {
7577 if (ii == N_TEST_CHILDREN)
7578 {
7579 FIB_TEST(1 == vec_len(tc->ctxs),
7580 "%d child visitsed %d times in zero quanta walk",
7581 ii, vec_len(tc->ctxs));
7582 }
7583 else
7584 {
7585 FIB_TEST(0 == vec_len(tc->ctxs),
7586 "%d child visitsed %d times in 0 quanta walk",
7587 ii, vec_len(tc->ctxs));
7588 }
7589 }
7590 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7591 "Queue is not empty post zero quanta walk");
7592 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7593 "Parent has %d children post zero qunta walk",
7594 fib_node_list_get_size(PARENT()->fn_children));
7595
7596 /*
7597 * another one step
7598 */
7599 fib_walk_process_queues(vm, 0);
7600
7601 FOR_EACH_TEST_CHILD(tc)
7602 {
7603 if (ii >= N_TEST_CHILDREN-1)
7604 {
7605 FIB_TEST(1 == vec_len(tc->ctxs),
7606 "%d child visitsed %d times in 2nd zero quanta walk",
7607 ii, vec_len(tc->ctxs));
7608 }
7609 else
7610 {
7611 FIB_TEST(0 == vec_len(tc->ctxs),
7612 "%d child visitsed %d times in 2nd 0 quanta walk",
7613 ii, vec_len(tc->ctxs));
7614 }
7615 }
7616 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7617 "Queue is not empty post zero quanta walk");
7618 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7619 "Parent has %d children post zero qunta walk",
7620 fib_node_list_get_size(PARENT()->fn_children));
7621
7622 /*
7623 * schedule another walk that will catch-up and merge.
7624 */
7625 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7626 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7627 fib_walk_process_queues(vm, 1);
7628
7629 FOR_EACH_TEST_CHILD(tc)
7630 {
7631 if (ii >= N_TEST_CHILDREN-1)
7632 {
7633 FIB_TEST(2 == vec_len(tc->ctxs),
7634 "%d child visitsed %d times in 2nd zero quanta merge walk",
7635 ii, vec_len(tc->ctxs));
7636 vec_free(tc->ctxs);
7637 }
7638 else
7639 {
7640 FIB_TEST(1 == vec_len(tc->ctxs),
7641 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7642 ii, vec_len(tc->ctxs));
7643 vec_free(tc->ctxs);
7644 }
7645 }
7646 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7647 "Queue is not empty post 2nd zero quanta merge walk");
7648 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7649 "Parent has %d children post 2nd zero qunta merge walk",
7650 fib_node_list_get_size(PARENT()->fn_children));
7651
7652 /*
7653 * park a async walk in the middle of the list, then have an sync walk catch
7654 * it. same expectations as async catches async.
7655 */
Neale Ranns450cd302016-11-09 17:49:42 +00007656 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007657
7658 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7659 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7660
7661 fib_walk_process_queues(vm, 0);
7662 fib_walk_process_queues(vm, 0);
7663
7664 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7665
7666 FOR_EACH_TEST_CHILD(tc)
7667 {
7668 if (ii >= N_TEST_CHILDREN-1)
7669 {
7670 FIB_TEST(2 == vec_len(tc->ctxs),
7671 "%d child visitsed %d times in sync catches async walk",
7672 ii, vec_len(tc->ctxs));
7673 vec_free(tc->ctxs);
7674 }
7675 else
7676 {
7677 FIB_TEST(1 == vec_len(tc->ctxs),
7678 "%d child visitsed %d times in sync catches async walk",
7679 ii, vec_len(tc->ctxs));
7680 vec_free(tc->ctxs);
7681 }
7682 }
7683 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7684 "Queue is not empty post 2nd zero quanta merge walk");
7685 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7686 "Parent has %d children post 2nd zero qunta merge walk",
7687 fib_node_list_get_size(PARENT()->fn_children));
7688
7689 /*
7690 * make the parent a child of one of its children, thus inducing a routing loop.
7691 */
7692 fib_test_nodes[PARENT_INDEX].sibling =
7693 fib_node_child_add(FIB_NODE_TYPE_TEST,
7694 1, // the first child
7695 FIB_NODE_TYPE_TEST,
7696 PARENT_INDEX);
7697
7698 /*
7699 * execute a sync walk from the parent. each child visited spawns more sync
7700 * walks. we expect the walk to terminate.
7701 */
7702 fib_test_walk_spawns_walks = 1;
7703
7704 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7705
7706 FOR_EACH_TEST_CHILD(tc)
7707 {
7708 /*
7709 * child 1 - which is last in the list - has the loop.
7710 * the other children a re thus visitsed first. the we meet
7711 * child 1. we go round the loop again, visting the other children.
7712 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7713 * again.
7714 */
7715 if (1 == ii)
7716 {
7717 FIB_TEST(1 == vec_len(tc->ctxs),
7718 "child %d visitsed %d times during looped sync walk",
7719 ii, vec_len(tc->ctxs));
7720 }
7721 else
7722 {
7723 FIB_TEST(2 == vec_len(tc->ctxs),
7724 "child %d visitsed %d times during looped sync walk",
7725 ii, vec_len(tc->ctxs));
7726 }
7727 vec_free(tc->ctxs);
7728 }
7729 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7730 "Parent has %d children post sync loop walk",
7731 fib_node_list_get_size(PARENT()->fn_children));
7732
7733 /*
7734 * the walk doesn't reach the max depth because the infra knows that sync
7735 * meets sync implies a loop and bails early.
7736 */
7737 FIB_TEST(high_ctx.fnbw_depth == 9,
7738 "Walk context depth %d post sync loop walk",
7739 high_ctx.fnbw_depth);
7740
7741 /*
7742 * execute an async walk of the graph loop, with each child spawns sync walks
7743 */
7744 high_ctx.fnbw_depth = 0;
7745 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7746 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7747
7748 fib_walk_process_queues(vm, 1);
7749
7750 FOR_EACH_TEST_CHILD(tc)
7751 {
7752 /*
7753 * we don't really care how many times the children are visisted, as long as
7754 * it is more than once.
7755 */
7756 FIB_TEST(1 <= vec_len(tc->ctxs),
7757 "child %d visitsed %d times during looped aync spawns sync walk",
7758 ii, vec_len(tc->ctxs));
7759 vec_free(tc->ctxs);
7760 }
7761
7762 /*
7763 * execute an async walk of the graph loop, with each child spawns async walks
7764 */
7765 fib_test_walk_spawns_walks = 2;
7766 high_ctx.fnbw_depth = 0;
7767 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7768 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7769
7770 fib_walk_process_queues(vm, 1);
7771
7772 FOR_EACH_TEST_CHILD(tc)
7773 {
7774 /*
7775 * we don't really care how many times the children are visisted, as long as
7776 * it is more than once.
7777 */
7778 FIB_TEST(1 <= vec_len(tc->ctxs),
7779 "child %d visitsed %d times during looped async spawns async walk",
7780 ii, vec_len(tc->ctxs));
Neale Ranns2303cb12018-02-21 04:57:17 -08007781 vec_free(tc->ctxs);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007782 }
7783
7784
7785 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7786 1, // the first child
7787 fib_test_nodes[PARENT_INDEX].sibling);
7788
7789 /*
7790 * cleanup
7791 */
7792 FOR_EACH_TEST_CHILD(tc)
7793 {
7794 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7795 tc->sibling);
7796 fib_node_deinit(&tc->node);
7797 fib_node_unlock(&tc->node);
7798 }
7799 fib_node_deinit(PARENT());
7800
7801 /*
7802 * The parent will be destroyed when the last lock on it goes.
7803 * this test ensures all the walk objects are unlocking it.
7804 */
7805 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7806 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007807
Neale Ranns2303cb12018-02-21 04:57:17 -08007808 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007809}
7810
Neale Ranns88fc83e2017-04-05 08:11:14 -07007811/*
7812 * declaration of the otherwise static callback functions
7813 */
7814void fib_bfd_notify (bfd_listen_event_e event,
7815 const bfd_session_t *session);
7816void adj_bfd_notify (bfd_listen_event_e event,
7817 const bfd_session_t *session);
7818
7819/**
7820 * Test BFD session interaction with FIB
7821 */
7822static int
7823fib_test_bfd (void)
7824{
7825 fib_node_index_t fei;
7826 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007827 int n_feis, res;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007828
Neale Ranns2303cb12018-02-21 04:57:17 -08007829 res = 0;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007830 /* via 10.10.10.1 */
7831 ip46_address_t nh_10_10_10_1 = {
7832 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7833 };
7834 /* via 10.10.10.2 */
7835 ip46_address_t nh_10_10_10_2 = {
7836 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7837 };
7838 /* via 10.10.10.10 */
7839 ip46_address_t nh_10_10_10_10 = {
7840 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7841 };
7842 n_feis = fib_entry_pool_size();
7843
7844 tm = &test_main;
7845
7846 /*
7847 * add interface routes. we'll assume this works. it's tested elsewhere
7848 */
7849 fib_prefix_t pfx_10_10_10_10_s_24 = {
7850 .fp_len = 24,
7851 .fp_proto = FIB_PROTOCOL_IP4,
7852 .fp_addr = nh_10_10_10_10,
7853 };
7854
7855 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7856 FIB_SOURCE_INTERFACE,
7857 (FIB_ENTRY_FLAG_CONNECTED |
7858 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007859 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007860 NULL,
7861 tm->hw[0]->sw_if_index,
7862 ~0, // invalid fib index
7863 1, // weight
7864 NULL,
7865 FIB_ROUTE_PATH_FLAG_NONE);
7866
7867 fib_prefix_t pfx_10_10_10_10_s_32 = {
7868 .fp_len = 32,
7869 .fp_proto = FIB_PROTOCOL_IP4,
7870 .fp_addr = nh_10_10_10_10,
7871 };
7872 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7873 FIB_SOURCE_INTERFACE,
7874 (FIB_ENTRY_FLAG_CONNECTED |
7875 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007876 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007877 NULL,
7878 tm->hw[0]->sw_if_index,
7879 ~0, // invalid fib index
7880 1, // weight
7881 NULL,
7882 FIB_ROUTE_PATH_FLAG_NONE);
7883
7884 /*
7885 * A BFD session via a neighbour we do not yet know
7886 */
7887 bfd_session_t bfd_10_10_10_1 = {
7888 .udp = {
7889 .key = {
7890 .fib_index = 0,
7891 .peer_addr = nh_10_10_10_1,
7892 },
7893 },
7894 .hop_type = BFD_HOP_TYPE_MULTI,
7895 .local_state = BFD_STATE_init,
7896 };
7897
7898 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7899
7900 /*
7901 * A new entry will be created that forwards via the adj
7902 */
7903 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7904 VNET_LINK_IP4,
7905 &nh_10_10_10_1,
7906 tm->hw[0]->sw_if_index);
7907 fib_prefix_t pfx_10_10_10_1_s_32 = {
7908 .fp_addr = nh_10_10_10_1,
7909 .fp_len = 32,
7910 .fp_proto = FIB_PROTOCOL_IP4,
7911 };
7912 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7913 .type = FT_LB_ADJ,
7914 .adj = {
7915 .adj = ai_10_10_10_1,
7916 },
7917 };
7918
7919 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007920 FIB_TEST(!fib_test_validate_entry(fei,
7921 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7922 1,
7923 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007924 "BFD sourced %U via %U",
7925 format_fib_prefix, &pfx_10_10_10_1_s_32,
7926 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7927
7928 /*
7929 * Delete the BFD session. Expect the fib_entry to be removed
7930 */
7931 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7932
7933 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7934 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7935 "BFD sourced %U removed",
7936 format_fib_prefix, &pfx_10_10_10_1_s_32);
7937
7938 /*
7939 * Add the BFD source back
7940 */
7941 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7942
7943 /*
7944 * source the entry via the ADJ fib
7945 */
Neale Ranns81424992017-05-18 03:03:22 -07007946 fei = fib_table_entry_path_add(0,
7947 &pfx_10_10_10_1_s_32,
7948 FIB_SOURCE_ADJ,
7949 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007950 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007951 &nh_10_10_10_1,
7952 tm->hw[0]->sw_if_index,
7953 ~0, // invalid fib index
7954 1,
7955 NULL,
7956 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007957
7958 /*
7959 * Delete the BFD session. Expect the fib_entry to remain
7960 */
7961 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7962
7963 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007964 FIB_TEST(!fib_test_validate_entry(fei,
7965 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7966 1,
7967 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007968 "BFD sourced %U remains via %U",
7969 format_fib_prefix, &pfx_10_10_10_1_s_32,
7970 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7971
7972 /*
7973 * Add the BFD source back
7974 */
7975 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7976
7977 /*
7978 * Create another ADJ FIB
7979 */
7980 fib_prefix_t pfx_10_10_10_2_s_32 = {
7981 .fp_addr = nh_10_10_10_2,
7982 .fp_len = 32,
7983 .fp_proto = FIB_PROTOCOL_IP4,
7984 };
Neale Ranns81424992017-05-18 03:03:22 -07007985 fib_table_entry_path_add(0,
7986 &pfx_10_10_10_2_s_32,
7987 FIB_SOURCE_ADJ,
7988 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007989 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007990 &nh_10_10_10_2,
7991 tm->hw[0]->sw_if_index,
7992 ~0, // invalid fib index
7993 1,
7994 NULL,
7995 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007996 /*
7997 * A BFD session for the new ADJ FIB
7998 */
7999 bfd_session_t bfd_10_10_10_2 = {
8000 .udp = {
8001 .key = {
8002 .fib_index = 0,
8003 .peer_addr = nh_10_10_10_2,
8004 },
8005 },
8006 .hop_type = BFD_HOP_TYPE_MULTI,
8007 .local_state = BFD_STATE_init,
8008 };
8009
8010 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
8011
8012 /*
8013 * remove the adj-fib source whilst the session is present
8014 * then add it back
8015 */
8016 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07008017 fib_table_entry_path_add(0,
8018 &pfx_10_10_10_2_s_32,
8019 FIB_SOURCE_ADJ,
8020 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07008021 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07008022 &nh_10_10_10_2,
8023 tm->hw[0]->sw_if_index,
8024 ~0, // invalid fib index
8025 1,
8026 NULL,
8027 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008028
8029 /*
8030 * Before adding a recursive via the BFD tracked ADJ-FIBs,
8031 * bring one of the sessions UP, leave the other down
8032 */
8033 bfd_10_10_10_1.local_state = BFD_STATE_up;
8034 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8035 bfd_10_10_10_2.local_state = BFD_STATE_down;
8036 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8037
8038 /*
8039 * A recursive prefix via both of the ADJ FIBs
8040 */
8041 fib_prefix_t pfx_200_0_0_0_s_24 = {
8042 .fp_proto = FIB_PROTOCOL_IP4,
8043 .fp_len = 32,
8044 .fp_addr = {
8045 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
8046 },
8047 };
8048 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
8049
8050 dpo_10_10_10_1 =
8051 fib_entry_contribute_ip_forwarding(
8052 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
8053 dpo_10_10_10_2 =
8054 fib_entry_contribute_ip_forwarding(
8055 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
8056
8057 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
8058 .type = FT_LB_O_LB,
8059 .lb = {
8060 .lb = dpo_10_10_10_1->dpoi_index,
8061 },
8062 };
8063 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8064 .type = FT_LB_O_LB,
8065 .lb = {
8066 .lb = dpo_10_10_10_2->dpoi_index,
8067 },
8068 };
8069
8070 /*
8071 * A prefix via the adj-fib that is BFD down => DROP
8072 */
8073 fei = fib_table_entry_path_add(0,
8074 &pfx_200_0_0_0_s_24,
8075 FIB_SOURCE_API,
8076 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008077 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008078 &nh_10_10_10_2,
8079 ~0, // recursive
8080 0, // default fib index
8081 1,
8082 NULL,
8083 FIB_ROUTE_PATH_FLAG_NONE);
8084 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8085 "%U resolves via drop",
8086 format_fib_prefix, &pfx_200_0_0_0_s_24);
8087
8088 /*
8089 * add a path via the UP BFD adj-fib.
8090 * we expect that the DOWN BFD ADJ FIB is not used.
8091 */
8092 fei = fib_table_entry_path_add(0,
8093 &pfx_200_0_0_0_s_24,
8094 FIB_SOURCE_API,
8095 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008096 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008097 &nh_10_10_10_1,
8098 ~0, // recursive
8099 0, // default fib index
8100 1,
8101 NULL,
8102 FIB_ROUTE_PATH_FLAG_NONE);
8103
Neale Ranns2303cb12018-02-21 04:57:17 -08008104 FIB_TEST(!fib_test_validate_entry(fei,
8105 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8106 1,
8107 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008108 "Recursive %U only UP BFD adj-fibs",
8109 format_fib_prefix, &pfx_200_0_0_0_s_24);
8110
8111 /*
8112 * Send a BFD state change to UP - both sessions are now up
8113 * the recursive prefix should LB over both
8114 */
8115 bfd_10_10_10_2.local_state = BFD_STATE_up;
8116 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8117
8118
Neale Ranns2303cb12018-02-21 04:57:17 -08008119 FIB_TEST(!fib_test_validate_entry(fei,
8120 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8121 2,
8122 &lb_o_10_10_10_1,
8123 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008124 "Recursive %U via both UP BFD adj-fibs",
8125 format_fib_prefix, &pfx_200_0_0_0_s_24);
8126
8127 /*
8128 * Send a BFD state change to DOWN
8129 * the recursive prefix should exclude the down
8130 */
8131 bfd_10_10_10_2.local_state = BFD_STATE_down;
8132 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8133
8134
Neale Ranns2303cb12018-02-21 04:57:17 -08008135 FIB_TEST(!fib_test_validate_entry(fei,
8136 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8137 1,
8138 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008139 "Recursive %U via only UP",
8140 format_fib_prefix, &pfx_200_0_0_0_s_24);
8141
8142 /*
8143 * Delete the BFD session while it is in the DOWN state.
8144 * FIB should consider the entry's state as back up
8145 */
8146 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8147
Neale Ranns2303cb12018-02-21 04:57:17 -08008148 FIB_TEST(!fib_test_validate_entry(fei,
8149 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8150 2,
8151 &lb_o_10_10_10_1,
8152 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008153 "Recursive %U via both UP BFD adj-fibs post down session delete",
8154 format_fib_prefix, &pfx_200_0_0_0_s_24);
8155
8156 /*
8157 * Delete the BFD other session while it is in the UP state.
8158 */
8159 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8160
Neale Ranns2303cb12018-02-21 04:57:17 -08008161 FIB_TEST(!fib_test_validate_entry(fei,
8162 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8163 2,
8164 &lb_o_10_10_10_1,
8165 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008166 "Recursive %U via both UP BFD adj-fibs post up session delete",
8167 format_fib_prefix, &pfx_200_0_0_0_s_24);
8168
8169 /*
8170 * cleaup
8171 */
8172 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8173 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8174 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8175
8176 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8177 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8178
8179 adj_unlock(ai_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008180 /*
Neale Ranns88fc83e2017-04-05 08:11:14 -07008181 * test no-one left behind
8182 */
8183 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8184 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8185
8186 /*
8187 * Single-hop BFD tests
8188 */
8189 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8190 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8191
8192 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8193
8194 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8195 VNET_LINK_IP4,
8196 &nh_10_10_10_1,
8197 tm->hw[0]->sw_if_index);
8198 /*
8199 * whilst the BFD session is not signalled, the adj is up
8200 */
Neale Ranns4faab212018-07-16 06:12:33 -07008201 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on uninit session");
Neale Ranns88fc83e2017-04-05 08:11:14 -07008202
8203 /*
8204 * bring the BFD session up
8205 */
8206 bfd_10_10_10_1.local_state = BFD_STATE_up;
8207 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8208 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8209
8210 /*
8211 * bring the BFD session down
8212 */
8213 bfd_10_10_10_1.local_state = BFD_STATE_down;
8214 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8215 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8216
Neale Ranns88fc83e2017-04-05 08:11:14 -07008217 /*
8218 * add an attached next hop FIB entry via the down adj
8219 */
8220 fib_prefix_t pfx_5_5_5_5_s_32 = {
8221 .fp_addr = {
8222 .ip4 = {
8223 .as_u32 = clib_host_to_net_u32(0x05050505),
8224 },
8225 },
8226 .fp_len = 32,
8227 .fp_proto = FIB_PROTOCOL_IP4,
8228 };
8229
8230 fei = fib_table_entry_path_add(0,
8231 &pfx_5_5_5_5_s_32,
8232 FIB_SOURCE_CLI,
8233 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008234 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008235 &nh_10_10_10_1,
8236 tm->hw[0]->sw_if_index,
8237 ~0, // invalid fib index
8238 1,
8239 NULL,
8240 FIB_ROUTE_PATH_FLAG_NONE);
8241 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8242 "%U resolves via drop",
8243 format_fib_prefix, &pfx_5_5_5_5_s_32);
8244
8245 /*
8246 * Add a path via an ADJ that is up
8247 */
8248 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8249 VNET_LINK_IP4,
8250 &nh_10_10_10_2,
8251 tm->hw[0]->sw_if_index);
8252
8253 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8254 .type = FT_LB_ADJ,
8255 .adj = {
8256 .adj = ai_10_10_10_2,
8257 },
8258 };
8259 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8260
8261 fei = fib_table_entry_path_add(0,
8262 &pfx_5_5_5_5_s_32,
8263 FIB_SOURCE_CLI,
8264 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008265 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008266 &nh_10_10_10_2,
8267 tm->hw[0]->sw_if_index,
8268 ~0, // invalid fib index
8269 1,
8270 NULL,
8271 FIB_ROUTE_PATH_FLAG_NONE);
8272
Neale Ranns2303cb12018-02-21 04:57:17 -08008273 FIB_TEST(!fib_test_validate_entry(fei,
8274 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8275 1,
8276 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008277 "BFD sourced %U via %U",
8278 format_fib_prefix, &pfx_5_5_5_5_s_32,
8279 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8280
8281 /*
8282 * Bring up the down session - should now LB
8283 */
8284 bfd_10_10_10_1.local_state = BFD_STATE_up;
8285 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008286 FIB_TEST(!fib_test_validate_entry(fei,
8287 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8288 2,
8289 &adj_o_10_10_10_1,
8290 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008291 "BFD sourced %U via noth adjs",
8292 format_fib_prefix, &pfx_5_5_5_5_s_32);
8293
8294 /*
8295 * remove the BFD session state from the adj
8296 */
8297 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8298
8299 /*
8300 * clean-up
8301 */
8302 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8303 adj_unlock(ai_10_10_10_1);
8304 adj_unlock(ai_10_10_10_2);
8305
8306 /*
8307 * test no-one left behind
8308 */
8309 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8310 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -08008311
8312 return (res);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008313}
8314
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008315static int
8316lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008317{
8318 const mpls_label_t deag_label = 50;
Neale Ranns2303cb12018-02-21 04:57:17 -08008319 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns31ed7442018-02-23 05:29:09 -08008320 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008321 const u32 lfib_index = 0;
8322 const u32 fib_index = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008323 const dpo_id_t *dpo1;
8324 fib_node_index_t lfe;
Neale Ranns2303cb12018-02-21 04:57:17 -08008325 lookup_dpo_t *lkd;
8326 int lb_count, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008327 test_main_t *tm;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008328
Neale Ranns2303cb12018-02-21 04:57:17 -08008329 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008330 tm = &test_main;
8331 lb_count = pool_elts(load_balance_pool);
8332
8333 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08008334 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008335
8336 /*
8337 * MPLS enable an interface so we get the MPLS table created
8338 */
Neale Ranns2297af02017-09-12 09:45:04 -07008339 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008340 mpls_sw_interface_enable_disable(&mpls_main,
8341 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008342 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008343
Neale Rannsad422ed2016-11-02 14:20:04 +00008344 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008345 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Rannsad422ed2016-11-02 14:20:04 +00008346 };
8347 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8348 VNET_LINK_MPLS,
8349 &nh_10_10_10_1,
8350 tm->hw[0]->sw_if_index);
8351
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008352 /*
8353 * Test the specials stack properly.
8354 */
8355 fib_prefix_t exp_null_v6_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008356 .fp_proto = FIB_PROTOCOL_MPLS,
8357 .fp_eos = MPLS_EOS,
8358 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8359 .fp_payload_proto = DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008360 };
8361 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8362 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
Neale Ranns2303cb12018-02-21 04:57:17 -08008363 "%U/%U present",
8364 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8365 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008366 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008367 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8368 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008369 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8370 lkd = lookup_dpo_get(dpo1->dpoi_index);
8371
8372 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008373 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008374 format_mpls_unicast_label, deag_label,
8375 format_mpls_eos_bit, MPLS_EOS,
8376 lkd->lkd_fib_index,
8377 format_dpo_id, &dpo, 0);
8378 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8379 "%U/%U is dst deag",
8380 format_mpls_unicast_label, deag_label,
8381 format_mpls_eos_bit, MPLS_EOS);
8382 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8383 "%U/%U is lookup in interface's table",
8384 format_mpls_unicast_label, deag_label,
8385 format_mpls_eos_bit, MPLS_EOS);
8386 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8387 "%U/%U is %U dst deag",
8388 format_mpls_unicast_label, deag_label,
8389 format_mpls_eos_bit, MPLS_EOS,
8390 format_dpo_proto, lkd->lkd_proto);
8391
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008392 /*
8393 * A route deag route for EOS
8394 */
8395 fib_prefix_t pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008396 .fp_proto = FIB_PROTOCOL_MPLS,
8397 .fp_eos = MPLS_EOS,
8398 .fp_label = deag_label,
8399 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008400 };
Neale Ranns2303cb12018-02-21 04:57:17 -08008401 mpls_disp_dpo_t *mdd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008402 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008403 &pfx,
8404 FIB_SOURCE_CLI,
8405 FIB_ENTRY_FLAG_NONE,
8406 DPO_PROTO_IP4,
8407 &zero_addr,
8408 ~0,
8409 fib_index,
8410 1,
8411 NULL,
8412 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008413
8414 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008415 "%U/%U present",
8416 format_mpls_unicast_label, deag_label,
8417 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008418
8419 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008420 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8421 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008422 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
Neale Ranns31ed7442018-02-23 05:29:09 -08008423 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8424
8425 FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode),
8426 "%U/%U disp is pipe mode",
8427 format_mpls_unicast_label, deag_label,
8428 format_mpls_eos_bit, MPLS_EOS);
8429
8430 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008431
8432 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008433 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008434 format_mpls_unicast_label, deag_label,
8435 format_mpls_eos_bit, MPLS_EOS,
8436 lkd->lkd_fib_index,
8437 format_dpo_id, &dpo, 0);
8438 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8439 "%U/%U is dst deag",
8440 format_mpls_unicast_label, deag_label,
8441 format_mpls_eos_bit, MPLS_EOS);
8442 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8443 "%U/%U is %U dst deag",
8444 format_mpls_unicast_label, deag_label,
8445 format_mpls_eos_bit, MPLS_EOS,
8446 format_dpo_proto, lkd->lkd_proto);
8447
8448 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8449
8450 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8451 &pfx)),
8452 "%U/%U not present",
8453 format_mpls_unicast_label, deag_label,
8454 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns31ed7442018-02-23 05:29:09 -08008455 dpo_reset(&dpo);
8456
8457 /*
8458 * A route deag route for EOS with LSP mode uniform
8459 */
8460 fib_mpls_label_t *l_pops = NULL, l_pop = {
8461 .fml_value = MPLS_LABEL_POP,
8462 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
8463 };
8464 vec_add1(l_pops, l_pop);
8465 lfe = fib_table_entry_path_add(lfib_index,
8466 &pfx,
8467 FIB_SOURCE_CLI,
8468 FIB_ENTRY_FLAG_NONE,
8469 DPO_PROTO_IP4,
8470 &zero_addr,
8471 ~0,
8472 fib_index,
8473 1,
8474 l_pops,
8475 FIB_ROUTE_PATH_FLAG_NONE);
8476
8477 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8478 "%U/%U present",
8479 format_mpls_unicast_label, deag_label,
8480 format_mpls_eos_bit, MPLS_EOS);
8481
8482 fib_entry_contribute_forwarding(lfe,
8483 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8484 &dpo);
8485 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8486 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8487
8488 FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode),
8489 "%U/%U disp is uniform mode",
8490 format_mpls_unicast_label, deag_label,
8491 format_mpls_eos_bit, MPLS_EOS);
8492
8493 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
8494
8495 FIB_TEST((fib_index == lkd->lkd_fib_index),
8496 "%U/%U is deag in %d %U",
8497 format_mpls_unicast_label, deag_label,
8498 format_mpls_eos_bit, MPLS_EOS,
8499 lkd->lkd_fib_index,
8500 format_dpo_id, &dpo, 0);
8501 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8502 "%U/%U is dst deag",
8503 format_mpls_unicast_label, deag_label,
8504 format_mpls_eos_bit, MPLS_EOS);
8505 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8506 "%U/%U is %U dst deag",
8507 format_mpls_unicast_label, deag_label,
8508 format_mpls_eos_bit, MPLS_EOS,
8509 format_dpo_proto, lkd->lkd_proto);
8510
8511 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8512
8513 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8514 &pfx)),
8515 "%U/%U not present",
8516 format_mpls_unicast_label, deag_label,
8517 format_mpls_eos_bit, MPLS_EOS);
8518 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008519
8520 /*
8521 * A route deag route for non-EOS
8522 */
8523 pfx.fp_eos = MPLS_NON_EOS;
8524 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008525 &pfx,
8526 FIB_SOURCE_CLI,
8527 FIB_ENTRY_FLAG_NONE,
8528 DPO_PROTO_IP4,
8529 &zero_addr,
8530 ~0,
8531 lfib_index,
8532 1,
8533 NULL,
8534 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008535
8536 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008537 "%U/%U present",
8538 format_mpls_unicast_label, deag_label,
8539 format_mpls_eos_bit, MPLS_NON_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008540
8541 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008542 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8543 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008544 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8545 lkd = lookup_dpo_get(dpo1->dpoi_index);
8546
8547 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008548 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008549 format_mpls_unicast_label, deag_label,
8550 format_mpls_eos_bit, MPLS_NON_EOS,
8551 lkd->lkd_fib_index,
8552 format_dpo_id, &dpo, 0);
8553 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8554 "%U/%U is dst deag",
8555 format_mpls_unicast_label, deag_label,
8556 format_mpls_eos_bit, MPLS_NON_EOS);
8557
8558 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8559 "%U/%U is %U dst deag",
8560 format_mpls_unicast_label, deag_label,
8561 format_mpls_eos_bit, MPLS_NON_EOS,
8562 format_dpo_proto, lkd->lkd_proto);
8563
8564 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8565
8566 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008567 &pfx)),
8568 "%U/%U not present",
8569 format_mpls_unicast_label, deag_label,
8570 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008571
Neale Rannsad422ed2016-11-02 14:20:04 +00008572 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008573
Neale Rannsad422ed2016-11-02 14:20:04 +00008574 /*
8575 * An MPLS x-connect
8576 */
8577 fib_prefix_t pfx_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008578 .fp_len = 21,
8579 .fp_proto = FIB_PROTOCOL_MPLS,
8580 .fp_label = 1200,
8581 .fp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008582 };
8583 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008584 .type = FT_LB_LABEL_STACK_O_ADJ,
8585 .label_stack_o_adj = {
8586 .adj = ai_mpls_10_10_10_1,
8587 .label_stack_size = 4,
8588 .label_stack = {
8589 200, 300, 400, 500,
8590 },
8591 .eos = MPLS_NON_EOS,
8592 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008593 };
8594 dpo_id_t neos_1200 = DPO_INVALID;
8595 dpo_id_t ip_1200 = DPO_INVALID;
Neale Ranns31ed7442018-02-23 05:29:09 -08008596 fib_mpls_label_t *l200 = NULL;
8597 u32 ii;
8598 for (ii = 0; ii < 4; ii++)
8599 {
8600 fib_mpls_label_t fml = {
8601 .fml_value = 200 + (ii * 100),
8602 };
8603 vec_add1(l200, fml);
8604 };
Neale Rannsad422ed2016-11-02 14:20:04 +00008605
8606 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008607 &pfx_1200,
8608 FIB_SOURCE_API,
8609 FIB_ENTRY_FLAG_NONE,
8610 DPO_PROTO_IP4,
8611 &nh_10_10_10_1,
8612 tm->hw[0]->sw_if_index,
8613 ~0, // invalid fib index
8614 1,
8615 l200,
8616 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00008617
Neale Ranns2303cb12018-02-21 04:57:17 -08008618 FIB_TEST(!fib_test_validate_entry(lfe,
8619 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8620 1,
8621 &neos_o_10_10_10_1),
8622 "1200/0 LB 1 buckets via: "
8623 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00008624
8625 /*
8626 * A recursive route via the MPLS x-connect
8627 */
8628 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008629 .fp_len = 32,
8630 .fp_proto = FIB_PROTOCOL_IP4,
8631 .fp_addr = {
8632 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8633 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008634 };
8635 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008636 .frp_proto = DPO_PROTO_MPLS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008637 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008638 .frp_eos = MPLS_NON_EOS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008639 .frp_sw_if_index = ~0, // recurive
8640 .frp_fib_index = 0, // Default MPLS fib
8641 .frp_weight = 1,
8642 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8643 .frp_label_stack = NULL,
Neale Rannsad422ed2016-11-02 14:20:04 +00008644 };
8645 vec_add1(rpaths, rpath);
8646
8647 fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008648 &pfx_2_2_2_3_s_32,
8649 FIB_SOURCE_API,
8650 FIB_ENTRY_FLAG_NONE,
8651 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008652
8653 /*
8654 * A labelled recursive route via the MPLS x-connect
8655 */
8656 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008657 .fp_len = 32,
8658 .fp_proto = FIB_PROTOCOL_IP4,
8659 .fp_addr = {
8660 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8661 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008662 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008663 fib_mpls_label_t *l999 = NULL, fml_999 = {
8664 .fml_value = 999,
8665 };
8666 vec_add1(l999, fml_999);
Neale Rannsad422ed2016-11-02 14:20:04 +00008667 rpaths[0].frp_label_stack = l999,
8668
Neale Ranns2303cb12018-02-21 04:57:17 -08008669 fib_table_entry_path_add2(fib_index,
8670 &pfx_2_2_2_4_s_32,
8671 FIB_SOURCE_API,
8672 FIB_ENTRY_FLAG_NONE,
8673 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008674
8675 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008676 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8677 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008678 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008679 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8680 &neos_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008681
8682 fib_test_lb_bucket_t ip_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008683 .type = FT_LB_O_LB,
8684 .lb = {
8685 .lb = ip_1200.dpoi_index,
8686 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008687 };
8688 fib_test_lb_bucket_t mpls_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008689 .type = FT_LB_LABEL_O_LB,
8690 .label_o_lb = {
8691 .lb = neos_1200.dpoi_index,
8692 .label = 999,
8693 .eos = MPLS_EOS,
8694 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008695 };
8696
8697 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008698 FIB_TEST(!fib_test_validate_entry(lfe,
8699 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8700 1,
8701 &ip_o_1200),
8702 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008703 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008704 FIB_TEST(!fib_test_validate_entry(lfe,
8705 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8706 1,
8707 &mpls_o_1200),
8708 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008709
8710 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8711 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8712 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8713
8714 dpo_reset(&neos_1200);
8715 dpo_reset(&ip_1200);
8716
8717 /*
8718 * A recursive via a label that does not exist
8719 */
8720 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008721 .type = FT_LB_DROP,
8722 .special = {
8723 .adj = DPO_PROTO_IP4,
8724 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07008725 };
8726 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008727 .type = FT_LB_DROP,
8728 .special = {
8729 .adj = DPO_PROTO_MPLS,
8730 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008731 };
8732
8733 rpaths[0].frp_label_stack = NULL;
8734 lfe = fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008735 &pfx_2_2_2_4_s_32,
8736 FIB_SOURCE_API,
8737 FIB_ENTRY_FLAG_NONE,
8738 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008739
8740 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008741 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8742 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008743 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8744
Neale Ranns2303cb12018-02-21 04:57:17 -08008745 FIB_TEST(!fib_test_validate_entry(lfe,
8746 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8747 1,
8748 &bucket_drop),
8749 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008750 lfe = fib_table_lookup(fib_index, &pfx_1200);
Neale Ranns2303cb12018-02-21 04:57:17 -08008751 FIB_TEST(!fib_test_validate_entry(lfe,
8752 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8753 1,
8754 &bucket_drop),
8755 "1200/neos LB 1 buckets via: ip4-DROP");
8756 FIB_TEST(!fib_test_validate_entry(lfe,
8757 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8758 1,
8759 &mpls_bucket_drop),
8760 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008761
8762 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8763
8764 dpo_reset(&ip_1200);
8765
8766 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008767 * An rx-interface route.
8768 * like the tail of an mcast LSP
8769 */
8770 dpo_id_t idpo = DPO_INVALID;
8771
Neale Ranns43161a82017-08-12 02:12:00 -07008772 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08008773 tm->hw[0]->sw_if_index,
8774 &idpo);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008775
8776 fib_prefix_t pfx_2500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008777 .fp_len = 21,
8778 .fp_proto = FIB_PROTOCOL_MPLS,
8779 .fp_label = 2500,
8780 .fp_eos = MPLS_EOS,
8781 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008782 };
8783 fib_test_lb_bucket_t rx_intf_0 = {
8784 .type = FT_LB_INTF,
8785 .adj = {
8786 .adj = idpo.dpoi_index,
8787 },
8788 };
8789
8790 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008791 &pfx_2500,
8792 FIB_SOURCE_API,
8793 FIB_ENTRY_FLAG_NONE,
8794 DPO_PROTO_IP4,
8795 NULL,
8796 tm->hw[0]->sw_if_index,
8797 ~0, // invalid fib index
8798 0,
8799 NULL,
8800 FIB_ROUTE_PATH_INTF_RX);
8801 FIB_TEST(!fib_test_validate_entry(lfe,
8802 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8803 1,
8804 &rx_intf_0),
8805 "2500 rx-interface 0");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008806 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8807
8808 /*
8809 * An MPLS mulicast entry
8810 */
8811 fib_prefix_t pfx_3500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008812 .fp_len = 21,
8813 .fp_proto = FIB_PROTOCOL_MPLS,
8814 .fp_label = 3500,
8815 .fp_eos = MPLS_EOS,
8816 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008817 };
8818 fib_test_rep_bucket_t mc_0 = {
8819 .type = FT_REP_LABEL_O_ADJ,
Neale Ranns2303cb12018-02-21 04:57:17 -08008820 .label_o_adj = {
8821 .adj = ai_mpls_10_10_10_1,
8822 .label = 3300,
8823 .eos = MPLS_EOS,
8824 },
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008825 };
8826 fib_test_rep_bucket_t mc_intf_0 = {
8827 .type = FT_REP_INTF,
8828 .adj = {
8829 .adj = idpo.dpoi_index,
8830 },
8831 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008832 fib_mpls_label_t *l3300 = NULL, fml_3300 = {
8833 .fml_value = 3300,
8834 };
8835 vec_add1(l3300, fml_3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008836
8837 lfe = fib_table_entry_update_one_path(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008838 &pfx_3500,
8839 FIB_SOURCE_API,
8840 FIB_ENTRY_FLAG_MULTICAST,
8841 DPO_PROTO_IP4,
8842 &nh_10_10_10_1,
8843 tm->hw[0]->sw_if_index,
8844 ~0, // invalid fib index
8845 1,
8846 l3300,
8847 FIB_ROUTE_PATH_FLAG_NONE);
8848 FIB_TEST(!fib_test_validate_entry(lfe,
8849 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8850 1,
8851 &mc_0),
8852 "3500 via replicate over 10.10.10.1");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008853
8854 /*
8855 * MPLS Bud-node. Add a replication via an interface-receieve path
8856 */
8857 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008858 &pfx_3500,
8859 FIB_SOURCE_API,
8860 FIB_ENTRY_FLAG_MULTICAST,
8861 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008862 NULL,
8863 tm->hw[0]->sw_if_index,
8864 ~0, // invalid fib index
8865 0,
8866 NULL,
8867 FIB_ROUTE_PATH_INTF_RX);
Neale Ranns2303cb12018-02-21 04:57:17 -08008868 FIB_TEST(!fib_test_validate_entry(lfe,
8869 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8870 2,
8871 &mc_0,
8872 &mc_intf_0),
8873 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008874
8875 /*
8876 * Add a replication via an interface-free for-us path
8877 */
8878 fib_test_rep_bucket_t mc_disp = {
8879 .type = FT_REP_DISP_MFIB_LOOKUP,
8880 .adj = {
8881 .adj = idpo.dpoi_index,
8882 },
8883 };
8884 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008885 &pfx_3500,
8886 FIB_SOURCE_API,
8887 FIB_ENTRY_FLAG_MULTICAST,
8888 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008889 NULL,
8890 5, // rpf-id
8891 0, // default table
8892 0,
8893 NULL,
8894 FIB_ROUTE_PATH_RPF_ID);
Neale Ranns2303cb12018-02-21 04:57:17 -08008895 FIB_TEST(!fib_test_validate_entry(lfe,
8896 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8897 3,
8898 &mc_0,
8899 &mc_disp,
8900 &mc_intf_0),
8901 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008902
8903
Neale Ranns2303cb12018-02-21 04:57:17 -08008904
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008905 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8906 dpo_reset(&idpo);
8907
8908 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008909 * cleanup
8910 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008911 mpls_sw_interface_enable_disable(&mpls_main,
8912 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008913 0, 1);
8914 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008915
Neale Ranns31ed7442018-02-23 05:29:09 -08008916 FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
8917 "mpls_disp_dpo resources freed %d of %d",
8918 0, pool_elts(mpls_disp_dpo_pool));
Neale Rannsad422ed2016-11-02 14:20:04 +00008919 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008920 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008921 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008922 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008923 "interface_rx_dpo resources freed %d of %d",
Neale Ranns43161a82017-08-12 02:12:00 -07008924 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008925
Neale Ranns2303cb12018-02-21 04:57:17 -08008926 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008927}
8928
Neale Ranns89541992017-04-06 04:41:02 -07008929static int
8930fib_test_inherit (void)
8931{
8932 fib_node_index_t fei;
8933 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08008934 int n_feis, res;
Neale Ranns89541992017-04-06 04:41:02 -07008935
Neale Ranns2303cb12018-02-21 04:57:17 -08008936 res = 0;
Neale Ranns89541992017-04-06 04:41:02 -07008937 n_feis = fib_entry_pool_size();
8938 tm = &test_main;
8939
8940 const ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008941 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Ranns89541992017-04-06 04:41:02 -07008942 };
8943 const ip46_address_t nh_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008944 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8945 };
8946 const ip46_address_t nh_10_10_10_3 = {
8947 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
Neale Ranns89541992017-04-06 04:41:02 -07008948 };
8949 const ip46_address_t nh_10_10_10_16 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008950 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
Neale Ranns89541992017-04-06 04:41:02 -07008951 };
8952 const ip46_address_t nh_10_10_10_20 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008953 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
Neale Ranns89541992017-04-06 04:41:02 -07008954 };
8955 const ip46_address_t nh_10_10_10_21 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008956 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
Neale Ranns89541992017-04-06 04:41:02 -07008957 };
8958 const ip46_address_t nh_10_10_10_22 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008959 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
Neale Ranns89541992017-04-06 04:41:02 -07008960 };
8961 const ip46_address_t nh_10_10_10_255 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008962 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
Neale Ranns89541992017-04-06 04:41:02 -07008963 };
8964 const ip46_address_t nh_10_10_10_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008965 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
Neale Ranns89541992017-04-06 04:41:02 -07008966 };
8967 const ip46_address_t nh_10_10_0_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008968 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8969 };
8970 const ip46_address_t nh_11_11_11_11 = {
8971 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
8972 };
8973 const ip46_address_t nh_11_11_11_0 = {
8974 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b00),
Neale Ranns89541992017-04-06 04:41:02 -07008975 };
8976
8977 /*
8978 * prefixes at the base of a sub-tree
8979 */
8980 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8981 .fp_len = 32,
8982 .fp_proto = FIB_PROTOCOL_IP4,
8983 .fp_addr = nh_10_10_10_21,
8984 };
8985 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8986 .fp_len = 32,
8987 .fp_proto = FIB_PROTOCOL_IP4,
8988 .fp_addr = nh_10_10_10_22,
8989 };
8990 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8991 .fp_len = 32,
8992 .fp_proto = FIB_PROTOCOL_IP4,
8993 .fp_addr = nh_10_10_10_255,
8994 };
Neale Ranns2303cb12018-02-21 04:57:17 -08008995 const u32 N_PLS = fib_path_list_pool_size();
Neale Ranns89541992017-04-06 04:41:02 -07008996
8997 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08008998 &pfx_10_10_10_21_s_32,
8999 FIB_SOURCE_CLI,
9000 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009001 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009002 &pfx_10_10_10_22_s_32,
9003 FIB_SOURCE_CLI,
9004 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009005 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009006 &pfx_10_10_10_255_s_32,
9007 FIB_SOURCE_CLI,
9008 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009009
9010 /*
9011 * source an entry that pushes its state down the sub-tree
9012 */
9013 const fib_prefix_t pfx_10_10_10_16_s_28 = {
9014 .fp_len = 28,
9015 .fp_proto = FIB_PROTOCOL_IP4,
9016 .fp_addr = nh_10_10_10_16,
9017 };
9018 fib_table_entry_update_one_path(0,
9019 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009020 FIB_SOURCE_API,
9021 FIB_ENTRY_FLAG_COVERED_INHERIT,
9022 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009023 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009024 tm->hw[0]->sw_if_index,
9025 ~0,
9026 1,
9027 NULL,
9028 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009029
9030 /*
9031 * this covering entry and all those below it should have
9032 * the same forwarding information.
9033 */
9034 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9035 VNET_LINK_IP4,
9036 &nh_10_10_10_1,
9037 tm->hw[0]->sw_if_index);
9038 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009039 .type = FT_LB_ADJ,
9040 .adj = {
9041 .adj = ai_10_10_10_1,
9042 },
Neale Ranns89541992017-04-06 04:41:02 -07009043 };
9044
9045 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009046 FIB_TEST(!fib_test_validate_entry(fei,
9047 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9048 1,
9049 &adj_o_10_10_10_1),
9050 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009051 format_fib_prefix, &pfx_10_10_10_16_s_28);
9052 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009053 FIB_TEST(!fib_test_validate_entry(fei,
9054 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9055 1,
9056 &adj_o_10_10_10_1),
9057 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009058 format_fib_prefix, &pfx_10_10_10_21_s_32);
9059 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009060 FIB_TEST(!fib_test_validate_entry(fei,
9061 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9062 1,
9063 &adj_o_10_10_10_1),
9064 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009065 format_fib_prefix, &pfx_10_10_10_22_s_32);
9066 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9067 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9068 "%U resolves via drop",
9069 format_fib_prefix, &pfx_10_10_10_255_s_32);
9070
9071 /*
9072 * remove the inherting cover - covereds go back to drop
9073 */
9074 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9075
9076 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9077 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9078 "%U resolves via drop",
9079 format_fib_prefix, &pfx_10_10_10_21_s_32);
9080
9081 /*
9082 * source an entry that pushes its state down the sub-tree
9083 */
9084 const fib_prefix_t pfx_10_10_10_0_s_24 = {
9085 .fp_len = 24,
9086 .fp_proto = FIB_PROTOCOL_IP4,
9087 .fp_addr = nh_10_10_10_0,
9088 };
9089 fib_table_entry_update_one_path(0,
9090 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009091 FIB_SOURCE_API,
9092 FIB_ENTRY_FLAG_COVERED_INHERIT,
9093 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009094 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009095 tm->hw[0]->sw_if_index,
9096 ~0,
9097 1,
9098 NULL,
9099 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009100
9101 /*
9102 * whole sub-tree now covered
9103 */
9104 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009105 FIB_TEST(!fib_test_validate_entry(fei,
9106 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9107 1,
9108 &adj_o_10_10_10_1),
9109 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009110 format_fib_prefix, &pfx_10_10_10_0_s_24);
9111 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009112 FIB_TEST(!fib_test_validate_entry(fei,
9113 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9114 1,
9115 &adj_o_10_10_10_1),
9116 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009117 format_fib_prefix, &pfx_10_10_10_21_s_32);
9118 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009119 FIB_TEST(!fib_test_validate_entry(fei,
9120 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9121 1,
9122 &adj_o_10_10_10_1),
9123 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009124 format_fib_prefix, &pfx_10_10_10_22_s_32);
9125 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009126 FIB_TEST(!fib_test_validate_entry(fei,
9127 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9128 1,
9129 &adj_o_10_10_10_1),
9130 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009131 format_fib_prefix, &pfx_10_10_10_255_s_32);
9132
9133 /*
9134 * insert a more specific into the sub-tree - expect inheritance
9135 * this one is directly covered by the root
9136 */
9137 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009138 &pfx_10_10_10_16_s_28,
9139 FIB_SOURCE_CLI,
9140 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009141 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009142 FIB_TEST(!fib_test_validate_entry(fei,
9143 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9144 1,
9145 &adj_o_10_10_10_1),
9146 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009147 format_fib_prefix, &pfx_10_10_10_16_s_28);
9148
9149 /*
9150 * insert a more specific into the sub-tree - expect inheritance
9151 * this one is indirectly covered by the root
9152 */
9153 const fib_prefix_t pfx_10_10_10_20_s_30 = {
9154 .fp_len = 30,
9155 .fp_proto = FIB_PROTOCOL_IP4,
9156 .fp_addr = nh_10_10_10_20,
9157 };
9158 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009159 &pfx_10_10_10_20_s_30,
9160 FIB_SOURCE_CLI,
9161 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009162 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
Neale Ranns2303cb12018-02-21 04:57:17 -08009163 FIB_TEST(!fib_test_validate_entry(fei,
9164 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9165 1,
9166 &adj_o_10_10_10_1),
9167 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009168 format_fib_prefix, &pfx_10_10_10_20_s_30);
9169
9170 /*
9171 * remove the prefix from the middle of the sub-tree
9172 * the inherited source will be the only one remaining - expect
9173 * it to be withdrawn and hence the prefix is removed.
9174 */
9175 fib_table_entry_special_remove(0,
9176 &pfx_10_10_10_20_s_30,
9177 FIB_SOURCE_CLI);
9178 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9179 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9180 "%U gone",
9181 format_fib_prefix, &pfx_10_10_10_20_s_30);
9182
9183 /*
9184 * inheriting source is modifed - expect the modification to be present
9185 * throughout the sub-tree
9186 */
9187 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9188 VNET_LINK_IP4,
9189 &nh_10_10_10_2,
9190 tm->hw[0]->sw_if_index);
9191 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009192 .type = FT_LB_ADJ,
9193 .adj = {
9194 .adj = ai_10_10_10_2,
9195 },
Neale Ranns89541992017-04-06 04:41:02 -07009196 };
9197
9198 fib_table_entry_update_one_path(0,
9199 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009200 FIB_SOURCE_API,
9201 FIB_ENTRY_FLAG_COVERED_INHERIT,
9202 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009203 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009204 tm->hw[0]->sw_if_index,
9205 ~0,
9206 1,
9207 NULL,
9208 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009209 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009210 FIB_TEST(!fib_test_validate_entry(fei,
9211 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9212 1,
9213 &adj_o_10_10_10_2),
9214 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009215 format_fib_prefix, &pfx_10_10_10_21_s_32);
9216 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009217 FIB_TEST(!fib_test_validate_entry(fei,
9218 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9219 1,
9220 &adj_o_10_10_10_2),
9221 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009222 format_fib_prefix, &pfx_10_10_10_22_s_32);
9223 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009224 FIB_TEST(!fib_test_validate_entry(fei,
9225 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9226 1,
9227 &adj_o_10_10_10_2),
9228 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009229 format_fib_prefix, &pfx_10_10_10_255_s_32);
9230 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009231 FIB_TEST(!fib_test_validate_entry(fei,
9232 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9233 1,
9234 &adj_o_10_10_10_2),
9235 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009236 format_fib_prefix, &pfx_10_10_10_0_s_24);
9237
9238 /*
9239 * add the source that replaces inherited state.
9240 * inheriting source is not the best, so it doesn't push state.
9241 */
9242 fib_table_entry_update_one_path(0,
9243 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009244 FIB_SOURCE_PLUGIN_HI,
9245 FIB_ENTRY_FLAG_NONE,
9246 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009247 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009248 tm->hw[0]->sw_if_index,
9249 ~0,
9250 1,
9251 NULL,
9252 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009253 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009254 FIB_TEST(!fib_test_validate_entry(fei,
9255 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9256 1,
9257 &adj_o_10_10_10_1),
9258 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009259 format_fib_prefix, &pfx_10_10_10_0_s_24);
9260
9261 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9262 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9263 "%U resolves via drop",
9264 format_fib_prefix, &pfx_10_10_10_21_s_32);
9265 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9266 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9267 "%U resolves via drop",
9268 format_fib_prefix, &pfx_10_10_10_22_s_32);
9269 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9270 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9271 "%U resolves via drop",
9272 format_fib_prefix, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009273 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009274 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9275 "%U resolves via drop",
9276 format_fib_prefix, &pfx_10_10_10_16_s_28);
9277
9278 /*
9279 * withdraw the higher priority source and expect the inherited to return
9280 * throughout the sub-tree
9281 */
9282 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9283
9284 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009285 FIB_TEST(!fib_test_validate_entry(fei,
9286 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9287 1,
9288 &adj_o_10_10_10_2),
9289 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009290 format_fib_prefix, &pfx_10_10_10_21_s_32);
9291 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009292 FIB_TEST(!fib_test_validate_entry(fei,
9293 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9294 1,
9295 &adj_o_10_10_10_2),
9296 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009297 format_fib_prefix, &pfx_10_10_10_22_s_32);
9298 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009299 FIB_TEST(!fib_test_validate_entry(fei,
9300 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9301 1,
9302 &adj_o_10_10_10_2),
9303 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009304 format_fib_prefix, &pfx_10_10_10_255_s_32);
9305 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009306 FIB_TEST(!fib_test_validate_entry(fei,
9307 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9308 1,
9309 &adj_o_10_10_10_2),
9310 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009311 format_fib_prefix, &pfx_10_10_10_0_s_24);
9312 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009313 FIB_TEST(!fib_test_validate_entry(fei,
9314 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9315 1,
9316 &adj_o_10_10_10_2),
9317 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009318 format_fib_prefix, &pfx_10_10_10_16_s_28);
9319
9320 /*
9321 * source a covered entry in the sub-tree with the same inherting source
9322 * - expect that it now owns the sub-tree and thus over-rides its cover
9323 */
9324 fib_table_entry_update_one_path(0,
9325 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009326 FIB_SOURCE_API,
9327 FIB_ENTRY_FLAG_COVERED_INHERIT,
9328 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009329 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009330 tm->hw[0]->sw_if_index,
9331 ~0,
9332 1,
9333 NULL,
9334 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009335 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009336 FIB_TEST(!fib_test_validate_entry(fei,
9337 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9338 1,
9339 &adj_o_10_10_10_1),
9340 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009341 format_fib_prefix, &pfx_10_10_10_16_s_28);
9342 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009343 FIB_TEST(!fib_test_validate_entry(fei,
9344 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9345 1,
9346 &adj_o_10_10_10_1),
9347 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009348 format_fib_prefix, &pfx_10_10_10_22_s_32);
9349 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009350 FIB_TEST(!fib_test_validate_entry(fei,
9351 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9352 1,
9353 &adj_o_10_10_10_1),
9354 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009355 format_fib_prefix, &pfx_10_10_10_21_s_32);
9356
9357 /* these two unaffected by the sub-tree change */
9358 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009359 FIB_TEST(!fib_test_validate_entry(fei,
9360 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9361 1,
9362 &adj_o_10_10_10_2),
9363 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009364 format_fib_prefix, &pfx_10_10_10_255_s_32);
9365 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009366 FIB_TEST(!fib_test_validate_entry(fei,
9367 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9368 1,
9369 &adj_o_10_10_10_2),
9370 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009371 format_fib_prefix, &pfx_10_10_10_0_s_24);
9372
9373 /*
9374 * removes the more specific, expect the /24 to now re-owns the sub-tree
9375 */
9376 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9377
9378 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009379 FIB_TEST(!fib_test_validate_entry(fei,
9380 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9381 1,
9382 &adj_o_10_10_10_2),
9383 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009384 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009385 FIB_TEST(!fib_test_validate_entry(fei,
9386 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9387 1,
9388 &adj_o_10_10_10_2),
9389 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009390 format_fib_prefix, &pfx_10_10_10_21_s_32);
9391 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009392 FIB_TEST(!fib_test_validate_entry(fei,
9393 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9394 1,
9395 &adj_o_10_10_10_2),
9396 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009397 format_fib_prefix, &pfx_10_10_10_22_s_32);
9398 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009399 FIB_TEST(!fib_test_validate_entry(fei,
9400 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9401 1,
9402 &adj_o_10_10_10_2),
9403 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009404 format_fib_prefix, &pfx_10_10_10_255_s_32);
9405 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009406 FIB_TEST(!fib_test_validate_entry(fei,
9407 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9408 1,
9409 &adj_o_10_10_10_2),
9410 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009411 format_fib_prefix, &pfx_10_10_10_0_s_24);
9412 /*
9413 * modify the /24. expect the new forwarding to be pushed down
9414 */
9415 fib_table_entry_update_one_path(0,
9416 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009417 FIB_SOURCE_API,
9418 FIB_ENTRY_FLAG_COVERED_INHERIT,
9419 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009420 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009421 tm->hw[0]->sw_if_index,
9422 ~0,
9423 1,
9424 NULL,
9425 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009426 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009427 FIB_TEST(!fib_test_validate_entry(fei,
9428 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9429 1,
9430 &adj_o_10_10_10_1),
9431 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009432 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009433 FIB_TEST(!fib_test_validate_entry(fei,
9434 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9435 1,
9436 &adj_o_10_10_10_1),
9437 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009438 format_fib_prefix, &pfx_10_10_10_21_s_32);
9439 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009440 FIB_TEST(!fib_test_validate_entry(fei,
9441 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9442 1,
9443 &adj_o_10_10_10_1),
9444 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009445 format_fib_prefix, &pfx_10_10_10_22_s_32);
9446 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009447 FIB_TEST(!fib_test_validate_entry(fei,
9448 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9449 1,
9450 &adj_o_10_10_10_1),
9451 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009452 format_fib_prefix, &pfx_10_10_10_255_s_32);
9453 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009454 FIB_TEST(!fib_test_validate_entry(fei,
9455 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9456 1,
9457 &adj_o_10_10_10_1),
9458 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009459 format_fib_prefix, &pfx_10_10_10_0_s_24);
9460
9461 /*
9462 * add an entry less specific to /24. it should not own the /24's tree
9463 */
9464 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9465 .fp_len = 16,
9466 .fp_proto = FIB_PROTOCOL_IP4,
9467 .fp_addr = nh_10_10_0_0,
9468 };
9469 fib_table_entry_update_one_path(0,
9470 &pfx_10_10_0_0_s_16,
Neale Ranns2303cb12018-02-21 04:57:17 -08009471 FIB_SOURCE_API,
9472 FIB_ENTRY_FLAG_COVERED_INHERIT,
9473 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009474 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009475 tm->hw[0]->sw_if_index,
9476 ~0,
9477 1,
9478 NULL,
9479 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009480 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009481 FIB_TEST(!fib_test_validate_entry(fei,
9482 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9483 1,
9484 &adj_o_10_10_10_1),
9485 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009486 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009487 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009488 FIB_TEST(!fib_test_validate_entry(fei,
9489 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9490 1,
9491 &adj_o_10_10_10_1),
9492 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009493 format_fib_prefix, &pfx_10_10_10_22_s_32);
9494 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009495 FIB_TEST(!fib_test_validate_entry(fei,
9496 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9497 1,
9498 &adj_o_10_10_10_1),
9499 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009500 format_fib_prefix, &pfx_10_10_10_255_s_32);
9501 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009502 FIB_TEST(!fib_test_validate_entry(fei,
9503 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9504 1,
9505 &adj_o_10_10_10_1),
9506 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009507 format_fib_prefix, &pfx_10_10_10_0_s_24);
9508 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
Neale Ranns2303cb12018-02-21 04:57:17 -08009509 FIB_TEST(!fib_test_validate_entry(fei,
9510 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9511 1,
9512 &adj_o_10_10_10_2),
9513 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009514 format_fib_prefix, &pfx_10_10_0_0_s_16);
9515
9516 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08009517 * Add/remove an interposer source to a new /32
9518 */
9519 const fib_prefix_t pfx_11_11_11_11_s_32 = {
9520 .fp_len = 32,
9521 .fp_proto = FIB_PROTOCOL_IP4,
9522 .fp_addr = nh_11_11_11_11,
9523 };
9524
9525 fib_table_entry_update_one_path(0,
9526 &pfx_11_11_11_11_s_32,
9527 FIB_SOURCE_API,
9528 FIB_ENTRY_FLAG_NONE,
9529 DPO_PROTO_IP4,
9530 &nh_10_10_10_3,
9531 tm->hw[0]->sw_if_index,
9532 ~0,
9533 1,
9534 NULL,
9535 FIB_ROUTE_PATH_FLAG_NONE);
9536
9537 dpo_id_t interposer = DPO_INVALID;
9538 fib_mpls_label_t *l99 = NULL, fml_99 = {
9539 .fml_value = 99,
9540 };
9541 vec_add1(l99, fml_99);
9542
9543 mpls_label_dpo_create(l99,
9544 MPLS_EOS,
9545 DPO_PROTO_IP4,
9546 MPLS_LABEL_DPO_FLAG_NONE,
9547 punt_dpo_get(DPO_PROTO_MPLS),
9548 &interposer);
9549
9550 adj_index_t ai_10_10_10_3 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9551 VNET_LINK_IP4,
9552 &nh_10_10_10_3,
9553 tm->hw[0]->sw_if_index);
9554 fib_test_lb_bucket_t adj_o_10_10_10_3 = {
9555 .type = FT_LB_ADJ,
9556 .adj = {
9557 .adj = ai_10_10_10_3,
9558 },
9559 };
9560 fib_test_lb_bucket_t l99_o_10_10_10_3 = {
9561 .type = FT_LB_LABEL_O_ADJ,
9562 .label_o_adj = {
9563 .adj = ai_10_10_10_3,
9564 .label = 99,
9565 .eos = MPLS_EOS,
9566 },
9567 };
9568
9569 fei = fib_table_entry_special_dpo_add(0,
9570 &pfx_11_11_11_11_s_32,
9571 FIB_SOURCE_SPECIAL,
9572 FIB_ENTRY_FLAG_INTERPOSE,
9573 &interposer);
9574 FIB_TEST(!fib_test_validate_entry(fei,
9575 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9576 1,
9577 &l99_o_10_10_10_3),
9578 "%U via interposer adj",
9579 format_fib_prefix,&pfx_11_11_11_11_s_32);
9580
9581 fib_table_entry_special_remove(0,
9582 &pfx_11_11_11_11_s_32,
9583 FIB_SOURCE_SPECIAL);
9584 FIB_TEST(!fib_test_validate_entry(fei,
9585 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9586 1,
9587 &adj_o_10_10_10_3),
9588 "%U via 10.10.10.1",
9589 format_fib_prefix, &pfx_11_11_11_11_s_32);
9590
9591 /*
9592 * remove and re-add the second best API source while the interpose
9593 * is present
9594 */
9595 fei = fib_table_entry_special_dpo_add(0,
9596 &pfx_11_11_11_11_s_32,
9597 FIB_SOURCE_SPECIAL,
9598 FIB_ENTRY_FLAG_INTERPOSE,
9599 &interposer);
9600 FIB_TEST(!fib_test_validate_entry(fei,
9601 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9602 1,
9603 &l99_o_10_10_10_3),
9604 "%U via interposer adj",
9605 format_fib_prefix,&pfx_11_11_11_11_s_32);
9606
9607 FIB_TEST(2 == pool_elts(mpls_label_dpo_pool),
9608 "MPLS label pool: %d",
9609 pool_elts(mpls_label_dpo_pool));
9610
9611 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9612
9613 /*
9614 * the interpose does not get stacked when there are not valid paths
9615 */
9616 fib_test_lb_bucket_t bucket_drop = {
9617 .type = FT_LB_DROP,
9618 .special = {
9619 .adj = DPO_PROTO_IP4,
9620 },
9621 };
9622 FIB_TEST(!fib_test_validate_entry(fei,
9623 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9624 1,
9625 &bucket_drop),
9626 "%U via drop",
9627 format_fib_prefix,&pfx_11_11_11_11_s_32);
9628
9629 fib_table_entry_update_one_path(0,
9630 &pfx_11_11_11_11_s_32,
9631 FIB_SOURCE_API,
9632 FIB_ENTRY_FLAG_NONE,
9633 DPO_PROTO_IP4,
9634 &nh_10_10_10_3,
9635 tm->hw[0]->sw_if_index,
9636 ~0,
9637 1,
9638 NULL,
9639 FIB_ROUTE_PATH_FLAG_NONE);
9640 FIB_TEST(!fib_test_validate_entry(fei,
9641 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9642 1,
9643 &l99_o_10_10_10_3),
9644 "%U via interposer adj",
9645 format_fib_prefix,&pfx_11_11_11_11_s_32);
9646 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9647
9648 /*
9649 * add a cover for the interposed entry, so that we test it selects
9650 * the covers forwarding.
9651 */
9652 const fib_prefix_t pfx_11_11_11_0_s_24 = {
9653 .fp_len = 24,
9654 .fp_proto = FIB_PROTOCOL_IP4,
9655 .fp_addr = nh_11_11_11_0,
9656 };
9657 fib_table_entry_update_one_path(0,
9658 &pfx_11_11_11_0_s_24,
9659 FIB_SOURCE_API,
9660 FIB_ENTRY_FLAG_NONE,
9661 DPO_PROTO_IP4,
9662 &nh_10_10_10_3,
9663 tm->hw[0]->sw_if_index,
9664 ~0,
9665 1,
9666 NULL,
9667 FIB_ROUTE_PATH_FLAG_NONE);
9668 FIB_TEST(!fib_test_validate_entry(fei,
9669 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9670 1,
9671 &l99_o_10_10_10_3),
9672 "%U via interposer adj",
9673 format_fib_prefix,&pfx_11_11_11_11_s_32);
9674
9675 /*
9676 * multiple interpose sources on the same entry. Only the high
9677 * priority source gets to add the interpose.
9678 */
9679 dpo_id_t interposer2 = DPO_INVALID;
9680 fib_mpls_label_t *l100 = NULL, fml_100 = {
9681 .fml_value = 100,
9682 };
9683 vec_add1(l100, fml_100);
9684
9685 mpls_label_dpo_create(l100,
9686 MPLS_EOS,
9687 DPO_PROTO_IP4,
9688 MPLS_LABEL_DPO_FLAG_NONE,
9689 punt_dpo_get(DPO_PROTO_MPLS),
9690 &interposer2);
9691
9692 fei = fib_table_entry_special_dpo_add(0,
9693 &pfx_11_11_11_11_s_32,
9694 FIB_SOURCE_CLASSIFY,
9695 FIB_ENTRY_FLAG_INTERPOSE,
9696 &interposer2);
9697 FIB_TEST(!fib_test_validate_entry(fei,
9698 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9699 1,
9700 &l99_o_10_10_10_3),
9701 "%U via interposer label 99",
9702 format_fib_prefix,&pfx_11_11_11_11_s_32);
9703
9704 fib_test_lb_bucket_t l100_o_10_10_10_3 = {
9705 .type = FT_LB_LABEL_O_ADJ,
9706 .label_o_adj = {
9707 .adj = ai_10_10_10_3,
9708 .label = 100,
9709 .eos = MPLS_EOS,
9710 },
9711 };
9712
9713 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_SPECIAL);
9714
9715 FIB_TEST(!fib_test_validate_entry(fei,
9716 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9717 1,
9718 &l100_o_10_10_10_3),
9719 "%U via interposer label 99",
9720 format_fib_prefix,&pfx_11_11_11_11_s_32);
9721
9722 fib_table_entry_delete(0, &pfx_11_11_11_0_s_24, FIB_SOURCE_API);
9723 FIB_TEST(!fib_test_validate_entry(fei,
9724 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9725 1,
9726 &bucket_drop),
9727 "%U via drop",
9728 format_fib_prefix,&pfx_11_11_11_11_s_32);
9729 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_CLASSIFY);
9730
9731 /*
9732 * update a source to/from interpose.
9733 */
9734 /* fib_table_entry_update_one_path(0, */
9735 /* &pfx_11_11_11_0_s_24, */
9736 /* FIB_SOURCE_API, */
9737 /* FIB_ENTRY_FLAG_NONE, */
9738 /* DPO_PROTO_IP4, */
9739 /* &nh_10_10_10_3, */
9740 /* tm->hw[0]->sw_if_index, */
9741 /* ~0, */
9742 /* 1, */
9743 /* NULL, */
9744 /* FIB_ROUTE_PATH_FLAG_NONE); */
9745 /* fei = fib_table_entry_special_dpo_add(0, */
9746 /* &pfx_11_11_11_11_s_32, */
9747 /* FIB_SOURCE_API, */
9748 /* FIB_ENTRY_FLAG_INTERPOSE, */
9749 /* &interposer); */
9750 /* FIB_TEST(!fib_test_validate_entry(fei, */
9751 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9752 /* 1, */
9753 /* &l99_o_10_10_10_3), */
9754 /* "%U via interposer label 99", */
9755 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9756
9757 /* FIB_TEST(3 == pool_elts(mpls_label_dpo_pool), */
9758 /* "MPLS label pool: %d", */
9759 /* pool_elts(mpls_label_dpo_pool)); */
9760 /* FIB_TEST((2 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9761 /* "Interposer %d locks", */
9762 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9763
9764 /* fib_table_entry_update_one_path(0, */
9765 /* &pfx_11_11_11_11_s_32, */
9766 /* FIB_SOURCE_API, */
9767 /* FIB_ENTRY_FLAG_NONE, */
9768 /* DPO_PROTO_IP4, */
9769 /* &nh_10_10_10_2, */
9770 /* tm->hw[0]->sw_if_index, */
9771 /* ~0, */
9772 /* 1, */
9773 /* NULL, */
9774 /* FIB_ROUTE_PATH_FLAG_NONE); */
9775 /* FIB_TEST(!fib_test_validate_entry(fei, */
9776 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9777 /* 1, */
9778 /* &adj_o_10_10_10_2), */
9779 /* "%U via 10.10.10.2", */
9780 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9781
9782 /* FIB_TEST((1 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9783 /* "Interposer %d locks", */
9784 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9785 /* FIB_TEST(2 == pool_elts(mpls_label_dpo_pool), */
9786 /* "MPLS label pool: %d", */
9787 /* pool_elts(mpls_label_dpo_pool)); */
9788
9789 /* fei = fib_table_entry_special_dpo_add(0, */
9790 /* &pfx_11_11_11_11_s_32, */
9791 /* FIB_SOURCE_API, */
9792 /* FIB_ENTRY_FLAG_INTERPOSE, */
9793 /* &interposer); */
9794 /* FIB_TEST(!fib_test_validate_entry(fei, */
9795 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9796 /* 1, */
9797 /* &l99_o_10_10_10_3), */
9798 /* "%U via interposer label 99", */
9799 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9800
9801 /* fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API); */
9802
9803 /*
9804 * Add/remove an interposer source from the top of the subtrie. The
9805 * interposer source is not inherited.
9806 */
9807 fib_table_entry_update_one_path(0,
9808 &pfx_10_10_10_0_s_24,
9809 FIB_SOURCE_API,
9810 FIB_ENTRY_FLAG_COVERED_INHERIT,
9811 DPO_PROTO_IP4,
9812 &nh_10_10_10_3,
9813 tm->hw[0]->sw_if_index,
9814 ~0,
9815 1,
9816 NULL,
9817 FIB_ROUTE_PATH_FLAG_NONE);
9818 fei = fib_table_entry_special_dpo_add(0,
9819 &pfx_10_10_10_0_s_24,
9820 FIB_SOURCE_SPECIAL,
9821 FIB_ENTRY_FLAG_INTERPOSE,
9822 &interposer);
9823 FIB_TEST(!fib_test_validate_entry(fei,
9824 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9825 1,
9826 &l99_o_10_10_10_3),
9827 "%U via interposer label",
9828 format_fib_prefix,&pfx_10_10_10_0_s_24);
9829 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9830 FIB_TEST(!fib_test_validate_entry(fei,
9831 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9832 1,
9833 &bucket_drop),
9834 "%U via drop",
9835 format_fib_prefix, &pfx_10_10_10_21_s_32);
9836
9837 fib_table_entry_special_remove(0,
9838 &pfx_10_10_10_0_s_24,
9839 FIB_SOURCE_SPECIAL);
9840 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9841 FIB_TEST(!fib_test_validate_entry(fei,
9842 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9843 1,
9844 &adj_o_10_10_10_3),
9845 "%U via 10.10.10.1",
9846 format_fib_prefix, &pfx_10_10_10_0_s_24);
9847 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9848 FIB_TEST(!fib_test_validate_entry(fei,
9849 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9850 1,
9851 &adj_o_10_10_10_3),
9852 "%U via via 10.10.10.1",
9853 format_fib_prefix, &pfx_10_10_10_21_s_32);
9854
9855 /*
9856 * Add/remove an interposer source from the top of the subtrie. The
9857 * interposer source is inherited.
9858 */
9859 fei = fib_table_entry_special_dpo_add(0,
9860 &pfx_10_10_10_0_s_24,
9861 FIB_SOURCE_SPECIAL,
9862 (FIB_ENTRY_FLAG_COVERED_INHERIT |
9863 FIB_ENTRY_FLAG_INTERPOSE),
9864 &interposer);
9865 FIB_TEST(!fib_test_validate_entry(fei,
9866 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9867 1,
9868 &l99_o_10_10_10_3),
9869 "%U via interposer label",
9870 format_fib_prefix,&pfx_10_10_10_0_s_24);
9871
9872 /* interposer gets forwarding from the drop cli source */
9873 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9874 FIB_TEST(!fib_test_validate_entry(fei,
9875 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9876 1,
9877 &bucket_drop),
9878 "%U via drop",
9879 format_fib_prefix,&pfx_10_10_10_21_s_32);
9880
9881 fib_table_entry_update_one_path(0,
9882 &pfx_10_10_10_21_s_32,
9883 FIB_SOURCE_API,
9884 FIB_ENTRY_FLAG_NONE,
9885 DPO_PROTO_IP4,
9886 &nh_10_10_10_3,
9887 tm->hw[0]->sw_if_index,
9888 ~0,
9889 1,
9890 NULL,
9891 FIB_ROUTE_PATH_FLAG_NONE);
9892 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9893 /* interposer gets forwarding from the API source */
9894 FIB_TEST(!fib_test_validate_entry(fei,
9895 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9896 1,
9897 &l99_o_10_10_10_3),
9898 "%U via interposer label",
9899 format_fib_prefix,&pfx_10_10_10_21_s_32);
9900
9901 /*
Neale Ranns89541992017-04-06 04:41:02 -07009902 * cleanup
9903 */
Neale Ranns89541992017-04-06 04:41:02 -07009904 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
Neale Ranns2303cb12018-02-21 04:57:17 -08009905 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_API);
Neale Ranns89541992017-04-06 04:41:02 -07009906 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9907 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9908 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9909 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
Neale Ranns2303cb12018-02-21 04:57:17 -08009910 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_SPECIAL);
Neale Ranns89541992017-04-06 04:41:02 -07009911 adj_unlock(ai_10_10_10_1);
9912 adj_unlock(ai_10_10_10_2);
Neale Ranns2303cb12018-02-21 04:57:17 -08009913 adj_unlock(ai_10_10_10_3);
9914 dpo_reset(&interposer);
9915 dpo_reset(&interposer2);
9916 FIB_TEST(0 == pool_elts(mpls_label_dpo_pool),
9917 "MPLS label pool empty: %d",
9918 pool_elts(mpls_label_dpo_pool));
9919 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9920 FIB_TEST(N_PLS == fib_path_list_pool_size(),
9921 "number of path-lists: %d = %d",
9922 N_PLS, fib_path_list_pool_size());
Neale Ranns89541992017-04-06 04:41:02 -07009923
9924 /*
9925 * test the v6 tree walk.
Neale Ranns2303cb12018-02-21 04:57:17 -08009926 * a /64 that covers everything. a /96 that covers one /128
Neale Ranns89541992017-04-06 04:41:02 -07009927 * a second /128 covered only by the /64.
9928 */
9929 const fib_prefix_t pfx_2001_s_64 = {
9930 .fp_len = 64,
9931 .fp_proto = FIB_PROTOCOL_IP6,
9932 .fp_addr = {
9933 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009934 .as_u64 = {
9935 [0] = clib_host_to_net_u64(0x2001000000000000),
9936 [1] = clib_host_to_net_u64(0x0000000000000000),
9937 },
Neale Ranns89541992017-04-06 04:41:02 -07009938 },
9939 },
9940 };
9941 const fib_prefix_t pfx_2001_1_s_96 = {
9942 .fp_len = 96,
9943 .fp_proto = FIB_PROTOCOL_IP6,
9944 .fp_addr = {
9945 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009946 .as_u64 = {
9947 [0] = clib_host_to_net_u64(0x2001000000000000),
9948 [1] = clib_host_to_net_u64(0x1000000000000000),
9949 },
Neale Ranns89541992017-04-06 04:41:02 -07009950 },
9951 },
9952 };
9953 const fib_prefix_t pfx_2001_1_1_s_128 = {
9954 .fp_len = 128,
9955 .fp_proto = FIB_PROTOCOL_IP6,
9956 .fp_addr = {
9957 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009958 .as_u64 = {
9959 [0] = clib_host_to_net_u64(0x2001000000000000),
9960 [1] = clib_host_to_net_u64(0x1000000000000001),
9961 },
Neale Ranns89541992017-04-06 04:41:02 -07009962 },
9963 },
9964 };
9965 const fib_prefix_t pfx_2001_0_1_s_128 = {
9966 .fp_len = 128,
9967 .fp_proto = FIB_PROTOCOL_IP6,
9968 .fp_addr = {
9969 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009970 .as_u64 = {
9971 [0] = clib_host_to_net_u64(0x2001000000000000),
9972 [1] = clib_host_to_net_u64(0x0000000000000001),
9973 },
Neale Ranns89541992017-04-06 04:41:02 -07009974 },
9975 },
9976 };
9977 const ip46_address_t nh_3000_1 = {
9978 .ip6 = {
9979 .as_u64 = {
9980 [0] = clib_host_to_net_u64(0x3000000000000000),
9981 [1] = clib_host_to_net_u64(0x0000000000000001),
9982 },
9983 },
9984 };
9985 const ip46_address_t nh_3000_2 = {
9986 .ip6 = {
9987 .as_u64 = {
9988 [0] = clib_host_to_net_u64(0x3000000000000000),
9989 [1] = clib_host_to_net_u64(0x0000000000000002),
9990 },
9991 },
9992 };
9993 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9994 VNET_LINK_IP6,
9995 &nh_3000_1,
9996 tm->hw[0]->sw_if_index);
9997 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9998 VNET_LINK_IP6,
9999 &nh_3000_2,
10000 tm->hw[0]->sw_if_index);
10001 fib_test_lb_bucket_t adj_o_3000_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010002 .type = FT_LB_ADJ,
10003 .adj = {
10004 .adj = ai_3000_1,
10005 },
Neale Ranns89541992017-04-06 04:41:02 -070010006 };
10007 fib_test_lb_bucket_t adj_o_3000_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010008 .type = FT_LB_ADJ,
10009 .adj = {
10010 .adj = ai_3000_2,
10011 },
Neale Ranns89541992017-04-06 04:41:02 -070010012 };
10013
10014 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010015 &pfx_2001_0_1_s_128,
10016 FIB_SOURCE_CLI,
10017 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010018 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010019 &pfx_2001_1_1_s_128,
10020 FIB_SOURCE_CLI,
10021 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010022
10023 /*
10024 * /96 has inherited forwarding pushed down to its covered /128
10025 */
10026 fib_table_entry_update_one_path(0,
10027 &pfx_2001_1_s_96,
Neale Ranns2303cb12018-02-21 04:57:17 -080010028 FIB_SOURCE_API,
10029 FIB_ENTRY_FLAG_COVERED_INHERIT,
10030 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010031 &nh_3000_1,
Neale Ranns2303cb12018-02-21 04:57:17 -080010032 tm->hw[0]->sw_if_index,
10033 ~0,
10034 1,
10035 NULL,
10036 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010037 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
Neale Ranns2303cb12018-02-21 04:57:17 -080010038 FIB_TEST(!fib_test_validate_entry(fei,
10039 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10040 1,
10041 &adj_o_3000_1),
10042 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010043 format_fib_prefix, &pfx_2001_1_s_96);
10044 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010045 FIB_TEST(!fib_test_validate_entry(fei,
10046 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10047 1,
10048 &adj_o_3000_1),
10049 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010050 format_fib_prefix, &pfx_2001_1_1_s_128);
10051 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
10052 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
10053 "%U resolves via drop",
10054 format_fib_prefix, &pfx_2001_0_1_s_128);
10055
10056 /*
10057 * /64 has inherited forwarding pushed down to all, but the /96
10058 * and its sub-tree remain unaffected.
10059 */
10060 fib_table_entry_update_one_path(0,
10061 &pfx_2001_s_64,
Neale Ranns2303cb12018-02-21 04:57:17 -080010062 FIB_SOURCE_API,
10063 FIB_ENTRY_FLAG_COVERED_INHERIT,
10064 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010065 &nh_3000_2,
Neale Ranns2303cb12018-02-21 04:57:17 -080010066 tm->hw[0]->sw_if_index,
10067 ~0,
10068 1,
10069 NULL,
10070 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010071
10072 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
Neale Ranns2303cb12018-02-21 04:57:17 -080010073 FIB_TEST(!fib_test_validate_entry(fei,
10074 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10075 1,
10076 &adj_o_3000_2),
10077 "%U via 3000::2",
Neale Ranns89541992017-04-06 04:41:02 -070010078 format_fib_prefix, &pfx_2001_s_64);
10079 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010080 FIB_TEST(!fib_test_validate_entry(fei,
10081 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10082 1,
10083 &adj_o_3000_2),
10084 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010085 format_fib_prefix, &pfx_2001_0_1_s_128);
10086
10087 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
Neale Ranns2303cb12018-02-21 04:57:17 -080010088 FIB_TEST(!fib_test_validate_entry(fei,
10089 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10090 1,
10091 &adj_o_3000_1),
10092 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010093 format_fib_prefix, &pfx_2001_1_s_96);
10094 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010095 FIB_TEST(!fib_test_validate_entry(fei,
10096 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10097 1,
10098 &adj_o_3000_1),
10099 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010100 format_fib_prefix, &pfx_2001_1_1_s_128);
10101
10102 /*
10103 * Cleanup
10104 */
10105 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
10106 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
10107 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
10108 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
10109 adj_unlock(ai_3000_1);
10110 adj_unlock(ai_3000_2);
10111
10112 /*
10113 * test no-one left behind
10114 */
10115 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
10116 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -080010117
10118 return (res);
Neale Ranns89541992017-04-06 04:41:02 -070010119}
10120
Neale Rannsac64b712018-10-08 14:51:11 +000010121static int
10122fib_test_sticky (void)
10123{
10124 fib_route_path_t *r_paths = NULL;
10125 test_main_t *tm = &test_main;
10126 u32 ii, lb_count, pl_count;
10127 dpo_id_t dpo = DPO_INVALID;
10128 fib_node_index_t pl_index;
10129 int res = 0;
10130#define N_PATHS 16
10131
10132 fib_test_lb_bucket_t buckets[N_PATHS];
10133 bfd_session_t bfds[N_PATHS] = {{0}};
10134
10135 lb_count = pool_elts(load_balance_pool);
10136 pl_count = fib_path_list_pool_size();
10137
10138 for (ii = 0; ii < N_PATHS; ii++)
10139 {
10140 ip46_address_t nh = {
10141 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
10142 };
10143 adj_index_t ai;
10144
10145 ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
10146 VNET_LINK_IP4,
10147 &nh, tm->hw[0]->sw_if_index);
10148
10149 buckets[ii].type = FT_LB_ADJ;
10150 buckets[ii].adj.adj = ai;
10151
10152 bfds[ii].udp.key.peer_addr = nh;
10153 bfds[ii].udp.key.sw_if_index = tm->hw[0]->sw_if_index;
10154 bfds[ii].hop_type = BFD_HOP_TYPE_SINGLE;
10155 bfds[ii].local_state = BFD_STATE_init;
10156 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfds[ii]);
10157 bfds[ii].local_state = BFD_STATE_up;
10158 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[ii]);
10159 }
10160
10161 for (ii = 0; ii < N_PATHS; ii++)
10162 {
10163 fib_route_path_t r_path = {
10164 .frp_proto = DPO_PROTO_IP4,
10165 .frp_addr = {
10166 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
10167 },
10168 .frp_sw_if_index = tm->hw[0]->sw_if_index,
10169 .frp_weight = 1,
10170 .frp_fib_index = ~0,
10171 };
10172 vec_add1(r_paths, r_path);
10173 };
10174
10175 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths);
10176 fib_path_list_lock(pl_index);
10177
10178 fib_path_list_contribute_forwarding(pl_index,
10179 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10180 FIB_PATH_LIST_FWD_FLAG_STICKY,
10181 &dpo);
10182
10183 FIB_TEST(!fib_test_validate_lb(&dpo,
10184 16,
10185 &buckets[0],
10186 &buckets[1],
10187 &buckets[2],
10188 &buckets[3],
10189 &buckets[4],
10190 &buckets[5],
10191 &buckets[6],
10192 &buckets[7],
10193 &buckets[8],
10194 &buckets[9],
10195 &buckets[10],
10196 &buckets[11],
10197 &buckets[12],
10198 &buckets[13],
10199 &buckets[14],
10200 &buckets[15]),
10201 "Setup OK");
10202
10203 /* take down paths */
10204 bfds[0].local_state = BFD_STATE_down;
10205 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
10206
10207 fib_path_list_contribute_forwarding(pl_index,
10208 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10209 FIB_PATH_LIST_FWD_FLAG_STICKY,
10210 &dpo);
10211
10212 FIB_TEST(!fib_test_validate_lb(&dpo,
10213 16,
10214 &buckets[1],
10215 &buckets[1],
10216 &buckets[2],
10217 &buckets[3],
10218 &buckets[4],
10219 &buckets[5],
10220 &buckets[6],
10221 &buckets[7],
10222 &buckets[8],
10223 &buckets[9],
10224 &buckets[10],
10225 &buckets[11],
10226 &buckets[12],
10227 &buckets[13],
10228 &buckets[14],
10229 &buckets[15]),
10230 "Failed at shut-down path 0");
10231
10232 bfds[7].local_state = BFD_STATE_down;
10233 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
10234
10235 fib_path_list_contribute_forwarding(pl_index,
10236 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10237 FIB_PATH_LIST_FWD_FLAG_STICKY,
10238 &dpo);
10239
10240 FIB_TEST(!fib_test_validate_lb(&dpo,
10241 16,
10242 &buckets[1],
10243 &buckets[1],
10244 &buckets[2],
10245 &buckets[3],
10246 &buckets[4],
10247 &buckets[5],
10248 &buckets[6],
10249 &buckets[2],
10250 &buckets[8],
10251 &buckets[9],
10252 &buckets[10],
10253 &buckets[11],
10254 &buckets[12],
10255 &buckets[13],
10256 &buckets[14],
10257 &buckets[15]),
10258 "Failed at shut-down path 7");
10259
10260 /* paths back up */
10261 bfds[0].local_state = BFD_STATE_up;
10262 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
10263 bfds[7].local_state = BFD_STATE_up;
10264 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
10265
10266 fib_path_list_contribute_forwarding(pl_index,
10267 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10268 FIB_PATH_LIST_FWD_FLAG_STICKY,
10269 &dpo);
10270
10271 FIB_TEST(!fib_test_validate_lb(&dpo,
10272 16,
10273 &buckets[0],
10274 &buckets[1],
10275 &buckets[2],
10276 &buckets[3],
10277 &buckets[4],
10278 &buckets[5],
10279 &buckets[6],
10280 &buckets[7],
10281 &buckets[8],
10282 &buckets[9],
10283 &buckets[10],
10284 &buckets[11],
10285 &buckets[12],
10286 &buckets[13],
10287 &buckets[14],
10288 &buckets[15]),
10289 "recovery OK");
10290
10291 fib_path_list_unlock(pl_index);
10292
10293 /*
10294 * non-power of 2 number of buckets
10295 */
10296 fib_route_path_t *r_paths2 = NULL;
10297
10298 r_paths2 = vec_dup(r_paths);
10299 _vec_len(r_paths2) = 3;
10300
10301 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths2);
10302 fib_path_list_lock(pl_index);
10303
10304 fib_path_list_contribute_forwarding(pl_index,
10305 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10306 FIB_PATH_LIST_FWD_FLAG_STICKY,
10307 &dpo);
10308
10309 FIB_TEST(!fib_test_validate_lb(&dpo,
10310 16,
10311 &buckets[0],
10312 &buckets[0],
10313 &buckets[0],
10314 &buckets[0],
10315 &buckets[0],
10316 &buckets[0],
10317 &buckets[1],
10318 &buckets[1],
10319 &buckets[1],
10320 &buckets[1],
10321 &buckets[1],
10322 &buckets[2],
10323 &buckets[2],
10324 &buckets[2],
10325 &buckets[2],
10326 &buckets[2]),
10327 "non-power of 2");
10328
10329 bfds[1].local_state = BFD_STATE_down;
10330 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10331
10332 fib_path_list_contribute_forwarding(pl_index,
10333 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10334 FIB_PATH_LIST_FWD_FLAG_STICKY,
10335 &dpo);
10336
10337 /*
10338 * path 1's buckets alternate between path 0 and 2
10339 */
10340 FIB_TEST(!fib_test_validate_lb(&dpo,
10341 16,
10342 &buckets[0],
10343 &buckets[0],
10344 &buckets[0],
10345 &buckets[0],
10346 &buckets[0],
10347 &buckets[0],
10348 &buckets[0],
10349 &buckets[2],
10350 &buckets[0],
10351 &buckets[2],
10352 &buckets[0],
10353 &buckets[2],
10354 &buckets[2],
10355 &buckets[2],
10356 &buckets[2],
10357 &buckets[2]),
10358 "non-power of 2");
10359 bfds[1].local_state = BFD_STATE_up;
10360 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10361
10362 fib_path_list_unlock(pl_index);
10363
10364 /*
10365 * unequal cost
10366 */
10367 fib_route_path_t *r_paths3 = NULL;
10368
10369 r_paths3 = vec_dup(r_paths);
10370 _vec_len(r_paths3) = 3;
10371
10372 r_paths3[0].frp_weight = 3;
10373
10374 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths3);
10375 fib_path_list_lock(pl_index);
10376
10377 fib_path_list_contribute_forwarding(pl_index,
10378 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10379 FIB_PATH_LIST_FWD_FLAG_STICKY,
10380 &dpo);
10381
10382 FIB_TEST(!fib_test_validate_lb(&dpo,
10383 16,
10384 &buckets[1],
10385 &buckets[1],
10386 &buckets[1],
10387 &buckets[2],
10388 &buckets[2],
10389 &buckets[2],
10390 &buckets[0],
10391 &buckets[0],
10392 &buckets[0],
10393 &buckets[0],
10394 &buckets[0],
10395 &buckets[0],
10396 &buckets[0],
10397 &buckets[0],
10398 &buckets[0],
10399 &buckets[0]),
10400 "UCMP");
10401
10402 bfds[1].local_state = BFD_STATE_down;
10403 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10404
10405 fib_path_list_contribute_forwarding(pl_index,
10406 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10407 FIB_PATH_LIST_FWD_FLAG_STICKY,
10408 &dpo);
10409 /* No attempt to Un-equal distribute the down path's buckets */
10410 FIB_TEST(!fib_test_validate_lb(&dpo,
10411 16,
10412 &buckets[2],
10413 &buckets[0],
10414 &buckets[2],
10415 &buckets[2],
10416 &buckets[2],
10417 &buckets[2],
10418 &buckets[0],
10419 &buckets[0],
10420 &buckets[0],
10421 &buckets[0],
10422 &buckets[0],
10423 &buckets[0],
10424 &buckets[0],
10425 &buckets[0],
10426 &buckets[0],
10427 &buckets[0]),
10428 "UCMP");
10429 bfds[1].local_state = BFD_STATE_up;
10430 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10431
10432 dpo_reset(&dpo);
10433 fib_path_list_unlock(pl_index);
10434
10435 vec_free(r_paths);
10436 vec_free(r_paths2);
10437 vec_free(r_paths3);
10438
10439 FIB_TEST(lb_count == pool_elts(load_balance_pool), "no leaked LBs");
10440 FIB_TEST(pl_count == fib_path_list_pool_size(), "no leaked PLs");
10441
10442 return 0;
10443}
10444
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010445static clib_error_t *
Neale Ranns2303cb12018-02-21 04:57:17 -080010446fib_test (vlib_main_t * vm,
10447 unformat_input_t * input,
10448 vlib_cli_command_t * cmd_arg)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010449{
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010450 int res;
10451
10452 res = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -080010453
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010454 fib_test_mk_intf(4);
10455
Neale Ranns88fc83e2017-04-05 08:11:14 -070010456 if (unformat (input, "debug"))
10457 {
10458 fib_test_do_debug = 1;
10459 }
10460
Neale Ranns2303cb12018-02-21 04:57:17 -080010461 if (unformat (input, "ip4"))
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010462 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010463 res += fib_test_v4();
10464 }
10465 else if (unformat (input, "ip6"))
10466 {
10467 res += fib_test_v6();
10468 }
10469 else if (unformat (input, "ip"))
10470 {
10471 res += fib_test_v4();
10472 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010473 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010474 else if (unformat (input, "label"))
10475 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010476 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010477 }
10478 else if (unformat (input, "ae"))
10479 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010480 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010481 }
Neale Ranns57b58602017-07-15 07:37:25 -070010482 else if (unformat (input, "pref"))
10483 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010484 res += fib_test_pref();
Neale Ranns57b58602017-07-15 07:37:25 -070010485 }
Neale Rannsad422ed2016-11-02 14:20:04 +000010486 else if (unformat (input, "lfib"))
10487 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010488 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +000010489 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010490 else if (unformat (input, "walk"))
10491 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010492 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010493 }
Neale Ranns88fc83e2017-04-05 08:11:14 -070010494 else if (unformat (input, "bfd"))
10495 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010496 res += fib_test_bfd();
Neale Ranns88fc83e2017-04-05 08:11:14 -070010497 }
Neale Ranns89541992017-04-06 04:41:02 -070010498 else if (unformat (input, "inherit"))
10499 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010500 res += fib_test_inherit();
Neale Ranns89541992017-04-06 04:41:02 -070010501 }
Neale Rannsac64b712018-10-08 14:51:11 +000010502 else if (unformat (input, "sticky"))
10503 {
10504 res += fib_test_sticky();
10505 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010506 else
10507 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010508 res += fib_test_v4();
10509 res += fib_test_v6();
10510 res += fib_test_ae();
10511 res += fib_test_bfd();
10512 res += fib_test_pref();
10513 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -070010514 res += fib_test_inherit();
Neale Ranns2303cb12018-02-21 04:57:17 -080010515 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -070010516
10517 /*
10518 * fib-walk process must be disabled in order for the walk tests to work
10519 */
10520 fib_walk_process_disable();
10521 res += fib_test_walk();
10522 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010523 }
10524
Neale Ranns2303cb12018-02-21 04:57:17 -080010525 fflush(NULL);
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010526 if (res)
10527 {
10528 return clib_error_return(0, "FIB Unit Test Failed");
10529 }
10530 else
10531 {
10532 return (NULL);
10533 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010534}
10535
10536VLIB_CLI_COMMAND (test_fib_command, static) = {
10537 .path = "test fib",
10538 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
10539 .function = fib_test,
10540};
10541
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010542clib_error_t *
10543fib_test_init (vlib_main_t *vm)
10544{
10545 return 0;
10546}
10547
10548VLIB_INIT_FUNCTION (fib_test_init);