blob: e46f670269afe91924d8032b2a0758dadf979792 [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 Ranns93149bb2017-11-15 10:44:07 -0800643 if (FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
644 "Entry links to %U",
645 format_dpo_type, dpo->dpoi_type))
646 {
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 Ranns2303cb12018-02-21 04:57:17 -0800653 res = 0;
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;
668 fib_prefix_t pfx;
669 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 Ranns0bd36ea2016-11-16 11:47:44 +0000677 fib_entry_get_prefix(fei, &pfx);
678 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",
694 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 Ranns0f26c5a2017-03-01 15:12:11 -0800706 switch (pfx.fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000707 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800708 case FIB_PROTOCOL_IP4:
709 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:
712 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx.fp_addr.ip6);
713 break;
714 case FIB_PROTOCOL_MPLS:
715 {
716 mpls_unicast_header_t hdr = {
717 .label_exp_s_ttl = 0,
718 };
719
720 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);
722 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 */
854 if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
855 PNBR += 2;
856
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100857 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000858 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800859 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000860 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800861 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100862
863 /*
864 * add interface routes.
865 * validate presence of /24 attached and /32 recieve.
866 * test for the presence of the receive address in the glean and local adj
867 */
868 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800869 .fp_len = 24,
870 .fp_proto = FIB_PROTOCOL_IP4,
871 .fp_addr = {
872 .ip4 = {
873 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
874 },
875 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100876 };
877
878 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800879 FIB_SOURCE_INTERFACE,
880 (FIB_ENTRY_FLAG_CONNECTED |
881 FIB_ENTRY_FLAG_ATTACHED),
882 DPO_PROTO_IP4,
883 NULL,
884 tm->hw[0]->sw_if_index,
885 ~0, // invalid fib index
886 1, // weight
887 NULL,
888 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100889 fei = fib_table_lookup(fib_index, &local_pfx);
890 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
891 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -0800892 fib_entry_get_flags(fei)),
893 "Flags set on attached interface");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100894
895 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -0700896 FIB_TEST((FIB_NODE_INDEX_INVALID != ai),
897 "attached interface route adj present %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100898 adj = adj_get(ai);
899 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -0800900 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100901 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -0800902 &adj->sub_type.glean.receive_addr)),
903 "attached interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100904
905 local_pfx.fp_len = 32;
906 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800907 FIB_SOURCE_INTERFACE,
908 (FIB_ENTRY_FLAG_CONNECTED |
909 FIB_ENTRY_FLAG_LOCAL),
910 DPO_PROTO_IP4,
911 NULL,
912 tm->hw[0]->sw_if_index,
913 ~0, // invalid fib index
914 1, // weight
915 NULL,
916 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100917 fei = fib_table_lookup(fib_index, &local_pfx);
918 FIB_TEST(((FIB_ENTRY_FLAG_LOCAL | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -0800919 fib_entry_get_flags(fei)),
920 "Flags set on local interface");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100921
922 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
923
924 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -0800925 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
926 "RPF list for local length 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100927 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
928 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -0800929 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100930 receive_dpo_t *rd = receive_dpo_get(dpo->dpoi_index);
931
932 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -0800933 &rd->rd_addr)),
934 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100935
936 FIB_TEST((2 == fib_table_get_num_entries(fib_index,
937 FIB_PROTOCOL_IP4,
938 FIB_SOURCE_INTERFACE)),
939 "2 Interface Source'd prefixes");
940
941 /*
942 * +2 interface routes +2 non-shared path-lists
943 */
944 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +0000945 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800946 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000947 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800948 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100949
950 /*
951 * Modify the default route to be via an adj not yet known.
952 * this sources the defalut route with the API source, which is
953 * a higher preference to the DEFAULT_ROUTE source
954 */
955 pfx.fp_addr.ip4.as_u32 = 0;
956 pfx.fp_len = 0;
957 fib_table_entry_path_add(fib_index, &pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -0800958 FIB_SOURCE_API,
959 FIB_ENTRY_FLAG_NONE,
960 DPO_PROTO_IP4,
961 &nh_10_10_10_1,
962 tm->hw[0]->sw_if_index,
963 ~0, // invalid fib index
964 1,
965 NULL,
966 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100967 fei = fib_table_lookup(fib_index, &pfx);
968 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800969 "Flags set on API route");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100970
971 FIB_TEST((fei == dfrt), "default route same index");
972 ai = fib_entry_get_adj(fei);
973 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
974 adj = adj_get(ai);
975 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -0800976 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100977 FIB_TEST((0 == ip46_address_cmp(&nh_10_10_10_1, &adj->sub_type.nbr.next_hop)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800978 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100979 FIB_TEST((1 == fib_table_get_num_entries(fib_index,
980 FIB_PROTOCOL_IP4,
981 FIB_SOURCE_API)),
982 "1 API Source'd prefixes");
983
984 /*
985 * find the adj in the shared db
986 */
987 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -0800988 VNET_LINK_IP4,
989 &nh_10_10_10_1,
990 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100991 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
992 adj_unlock(locked_ai);
993
994 /*
995 * +1 shared path-list
996 */
997 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800998 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +0000999 FIB_TEST((PNBR+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001000 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001001 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001002 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001003
1004 /*
1005 * remove the API source from the default route. We expected
1006 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
1007 */
1008 pfx.fp_addr.ip4.as_u32 = 0;
1009 pfx.fp_len = 0;
1010 fib_table_entry_path_remove(fib_index, &pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08001011 FIB_SOURCE_API,
1012 DPO_PROTO_IP4,
1013 &nh_10_10_10_1,
1014 tm->hw[0]->sw_if_index,
1015 ~0, // non-recursive path, so no FIB index
1016 1,
1017 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001018
1019 fei = fib_table_lookup(fib_index, &pfx);
1020
1021 FIB_TEST((fei == dfrt), "default route same index");
1022 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001023 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001024
1025 /*
1026 * -1 shared-path-list
1027 */
1028 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001029 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001030 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001031 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001032 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001033
1034 /*
1035 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
1036 */
1037 fib_prefix_t pfx_10_10_10_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001038 .fp_len = 32,
1039 .fp_proto = FIB_PROTOCOL_IP4,
1040 .fp_addr = {
1041 /* 10.10.10.1 */
1042 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1043 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001044 };
1045 fib_prefix_t pfx_10_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001046 .fp_len = 32,
1047 .fp_proto = FIB_PROTOCOL_IP4,
1048 .fp_addr = {
1049 /* 10.10.10.2 */
1050 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
1051 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001052 };
1053 fib_prefix_t pfx_11_11_11_11_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001054 .fp_len = 32,
1055 .fp_proto = FIB_PROTOCOL_IP4,
1056 .fp_addr = {
1057 /* 11.11.11.11 */
1058 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
1059 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001060 };
1061 u8 eth_addr[] = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001062 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001063 };
Neale Rannsb80c5362016-10-08 13:03:40 +01001064
Neale Ranns3ee44042016-10-03 13:05:48 +01001065 ip46_address_t nh_12_12_12_12 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001066 .ip4.as_u32 = clib_host_to_net_u32(0x0c0c0c0c),
Neale Ranns3ee44042016-10-03 13:05:48 +01001067 };
1068 adj_index_t ai_12_12_12_12;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001069
1070 /*
1071 * Add a route via an incomplete ADJ. then complete the ADJ
1072 * Expect the route LB is updated to use complete adj type.
1073 */
1074 fei = fib_table_entry_update_one_path(fib_index,
1075 &pfx_11_11_11_11_s_32,
1076 FIB_SOURCE_API,
1077 FIB_ENTRY_FLAG_ATTACHED,
Neale Ranns2303cb12018-02-21 04:57:17 -08001078 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001079 &pfx_10_10_10_1_s_32.fp_addr,
1080 tm->hw[0]->sw_if_index,
1081 ~0, // invalid fib index
1082 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001083 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001084 FIB_ROUTE_PATH_FLAG_NONE);
1085
1086 dpo = fib_entry_contribute_ip_forwarding(fei);
1087 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1088 FIB_TEST(DPO_ADJACENCY_INCOMPLETE == dpo1->dpoi_type,
1089 "11.11.11.11/32 via incomplete adj");
1090
1091 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001092 VNET_LINK_IP4,
1093 &pfx_10_10_10_1_s_32.fp_addr,
1094 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001095 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
1096 adj = adj_get(ai_01);
1097 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001098 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001099 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001100 &adj->sub_type.nbr.next_hop)),
1101 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001102
Neale Rannsb80c5362016-10-08 13:03:40 +01001103 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001104 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001105 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001106 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001107 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_1_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001108 &adj->sub_type.nbr.next_hop)),
1109 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001110 ai = fib_entry_get_adj(fei);
1111 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
1112
1113 dpo = fib_entry_contribute_ip_forwarding(fei);
1114 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1115 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type,
1116 "11.11.11.11/32 via complete adj");
Neale Ranns2303cb12018-02-21 04:57:17 -08001117 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1118 tm->hw[0]->sw_if_index),
1119 "RPF list for adj-fib contains adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001120
1121 ai_12_12_12_12 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001122 VNET_LINK_IP4,
1123 &nh_12_12_12_12,
1124 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01001125 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_12_12_12_12), "adj created");
1126 adj = adj_get(ai_12_12_12_12);
1127 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001128 "adj is incomplete");
Neale Ranns3ee44042016-10-03 13:05:48 +01001129 FIB_TEST((0 == ip46_address_cmp(&nh_12_12_12_12,
Neale Ranns2303cb12018-02-21 04:57:17 -08001130 &adj->sub_type.nbr.next_hop)),
1131 "adj nbr next-hop ok");
Neale Rannsb80c5362016-10-08 13:03:40 +01001132 adj_nbr_update_rewrite(ai_12_12_12_12, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001133 fib_test_build_rewrite(eth_addr));
Neale Ranns3ee44042016-10-03 13:05:48 +01001134 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001135 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001136
1137 /*
1138 * add the adj fib
1139 */
Neale Ranns81424992017-05-18 03:03:22 -07001140 fei = fib_table_entry_path_add(fib_index,
1141 &pfx_10_10_10_1_s_32,
1142 FIB_SOURCE_ADJ,
1143 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001144 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001145 &pfx_10_10_10_1_s_32.fp_addr,
1146 tm->hw[0]->sw_if_index,
1147 ~0, // invalid fib index
1148 1,
1149 NULL,
1150 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001151 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001152 "Flags set on adj-fib");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001153 ai = fib_entry_get_adj(fei);
Neale Ranns81424992017-05-18 03:03:22 -07001154 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj, %d", ai);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001155
1156 fib_table_entry_path_remove(fib_index,
1157 &pfx_11_11_11_11_s_32,
1158 FIB_SOURCE_API,
Neale Ranns2303cb12018-02-21 04:57:17 -08001159 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001160 &pfx_10_10_10_1_s_32.fp_addr,
1161 tm->hw[0]->sw_if_index,
1162 ~0, // invalid fib index
1163 1,
1164 FIB_ROUTE_PATH_FLAG_NONE);
1165
1166 eth_addr[5] = 0xb2;
1167
1168 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001169 VNET_LINK_IP4,
1170 &pfx_10_10_10_2_s_32.fp_addr,
1171 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001172 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
1173 adj = adj_get(ai_02);
1174 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001175 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001176 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001177 &adj->sub_type.nbr.next_hop)),
1178 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001179
Neale Rannsb80c5362016-10-08 13:03:40 +01001180 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001181 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001182 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001183 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001184 FIB_TEST((0 == ip46_address_cmp(&pfx_10_10_10_2_s_32.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08001185 &adj->sub_type.nbr.next_hop)),
1186 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001187 FIB_TEST((ai_01 != ai_02), "ADJs are different");
1188
Neale Ranns81424992017-05-18 03:03:22 -07001189 fib_table_entry_path_add(fib_index,
1190 &pfx_10_10_10_2_s_32,
1191 FIB_SOURCE_ADJ,
1192 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07001193 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07001194 &pfx_10_10_10_2_s_32.fp_addr,
1195 tm->hw[0]->sw_if_index,
1196 ~0, // invalid fib index
1197 1,
1198 NULL,
1199 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001200
1201 fei = fib_table_lookup(fib_index, &pfx_10_10_10_2_s_32);
1202 ai = fib_entry_get_adj(fei);
1203 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
1204
1205 /*
1206 * +2 adj-fibs, and their non-shared path-lists
1207 */
1208 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001209 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001210 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001211 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001212 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001213
1214 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01001215 * Add 2 routes via the first ADJ. ensure path-list sharing
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001216 */
1217 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001218 .fp_len = 32,
1219 .fp_proto = FIB_PROTOCOL_IP4,
1220 .fp_addr = {
1221 /* 1.1.1.1/32 */
1222 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1223 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001224 };
1225
1226 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001227 &pfx_1_1_1_1_s_32,
1228 FIB_SOURCE_API,
1229 FIB_ENTRY_FLAG_NONE,
1230 DPO_PROTO_IP4,
1231 &nh_10_10_10_1,
1232 tm->hw[0]->sw_if_index,
1233 ~0, // invalid fib index
1234 1,
1235 NULL,
1236 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001237 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
1238 ai = fib_entry_get_adj(fei);
1239 FIB_TEST((ai_01 == ai), "1.1.1.1 resolves via 10.10.10.1");
1240
1241 /*
1242 * +1 entry and a shared path-list
1243 */
1244 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001245 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001246 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001247 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001248 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001249
1250 /* 1.1.2.0/24 */
1251 fib_prefix_t pfx_1_1_2_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001252 .fp_len = 24,
1253 .fp_proto = FIB_PROTOCOL_IP4,
1254 .fp_addr = {
1255 .ip4.as_u32 = clib_host_to_net_u32(0x01010200),
1256 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001257 };
1258
1259 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001260 &pfx_1_1_2_0_s_24,
1261 FIB_SOURCE_API,
1262 FIB_ENTRY_FLAG_NONE,
1263 DPO_PROTO_IP4,
1264 &nh_10_10_10_1,
1265 tm->hw[0]->sw_if_index,
1266 ~0, // invalid fib index
1267 1,
1268 NULL,
1269 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001270 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1271 ai = fib_entry_get_adj(fei);
1272 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1273
1274 /*
1275 * +1 entry only
1276 */
1277 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001278 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001279 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001280 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001281 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001282
1283 /*
1284 * modify 1.1.2.0/24 to use multipath.
1285 */
1286 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001287 &pfx_1_1_2_0_s_24,
1288 FIB_SOURCE_API,
1289 FIB_ENTRY_FLAG_NONE,
1290 DPO_PROTO_IP4,
1291 &nh_10_10_10_2,
1292 tm->hw[0]->sw_if_index,
1293 ~0, // invalid fib index
1294 1,
1295 NULL,
1296 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001297 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
1298 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08001299 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1300 1, tm->hw[0]->sw_if_index),
1301 "RPF list for 1.1.2.0/24 contains both adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001302
1303 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 0);
1304 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1305 FIB_TEST((ai_01 == dpo1->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001306 "1.1.2.0/24 bucket 0 resolves via 10.10.10.1 (%d=%d)",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001307 ai_01, dpo1->dpoi_index);
1308
1309 dpo1 = load_balance_get_bucket(dpo->dpoi_index, 1);
1310 FIB_TEST(DPO_ADJACENCY == dpo1->dpoi_type, "type is %d", dpo1->dpoi_type);
1311 FIB_TEST((ai_02 == dpo1->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08001312 "1.1.2.0/24 bucket 1 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001313
1314 /*
1315 * +1 shared-pathlist
1316 */
1317 FIB_TEST((2 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00001318 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001319 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001320 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001321 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001322
1323 /*
1324 * revert the modify
1325 */
1326 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001327 &pfx_1_1_2_0_s_24,
1328 FIB_SOURCE_API,
1329 DPO_PROTO_IP4,
1330 &nh_10_10_10_2,
1331 tm->hw[0]->sw_if_index,
1332 ~0,
1333 1,
1334 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001335 fei = fib_table_lookup(fib_index, &pfx_1_1_2_0_s_24);
Neale Ranns3ee44042016-10-03 13:05:48 +01001336 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08001337 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1338 1, tm->hw[0]->sw_if_index),
1339 "RPF list for 1.1.2.0/24 contains one adj");
Neale Ranns3ee44042016-10-03 13:05:48 +01001340
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001341 ai = fib_entry_get_adj(fei);
1342 FIB_TEST((ai_01 == ai), "1.1.2.0/24 resolves via 10.10.10.1");
1343
1344 /*
1345 * +1 shared-pathlist
1346 */
1347 FIB_TEST((1 == fib_path_list_db_size()), "path list DB is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001348 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001349 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001350 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001351 FIB_TEST((ENBR+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001352 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001353
1354 /*
1355 * Add 2 recursive routes:
1356 * 100.100.100.100/32 via 1.1.1.1/32 => the via entry is installed.
1357 * 100.100.100.101/32 via 1.1.1.1/32 => the via entry is installed.
1358 */
1359 fib_prefix_t bgp_100_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001360 .fp_len = 32,
1361 .fp_proto = FIB_PROTOCOL_IP4,
1362 .fp_addr = {
1363 /* 100.100.100.100/32 */
1364 .ip4.as_u32 = clib_host_to_net_u32(0x64646464),
1365 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001366 };
1367 /* via 1.1.1.1 */
1368 ip46_address_t nh_1_1_1_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001369 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001370 };
1371
Neale Ranns3ee44042016-10-03 13:05:48 +01001372 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001373 &bgp_100_pfx,
1374 FIB_SOURCE_API,
1375 FIB_ENTRY_FLAG_NONE,
1376 DPO_PROTO_IP4,
1377 &nh_1_1_1_1,
1378 ~0, // no index provided.
1379 fib_index, // nexthop in same fib as route
1380 1,
1381 NULL,
1382 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001383
Neale Ranns3ee44042016-10-03 13:05:48 +01001384 FIB_TEST_REC_FORW(&bgp_100_pfx, &pfx_1_1_1_1_s_32, 0);
Neale Ranns2303cb12018-02-21 04:57:17 -08001385 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1386 tm->hw[0]->sw_if_index),
1387 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001388
1389 /*
1390 * +1 entry and +1 shared-path-list
1391 */
1392 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001393 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001394 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001395 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001396 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001397 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001398
1399 fib_prefix_t bgp_101_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001400 .fp_len = 32,
1401 .fp_proto = FIB_PROTOCOL_IP4,
1402 .fp_addr = {
1403 /* 100.100.100.101/32 */
1404 .ip4.as_u32 = clib_host_to_net_u32(0x64646465),
1405 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001406 };
1407
1408 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001409 &bgp_101_pfx,
1410 FIB_SOURCE_API,
1411 FIB_ENTRY_FLAG_NONE,
1412 DPO_PROTO_IP4,
1413 &nh_1_1_1_1,
1414 ~0, // no index provided.
1415 fib_index, // nexthop in same fib as route
1416 1,
1417 NULL,
1418 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001419
Neale Ranns3ee44042016-10-03 13:05:48 +01001420 FIB_TEST_REC_FORW(&bgp_101_pfx, &pfx_1_1_1_1_s_32, 0);
Neale Ranns2303cb12018-02-21 04:57:17 -08001421 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
1422 tm->hw[0]->sw_if_index),
1423 "RPF list for adj-fib contains adj");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001424
1425 /*
1426 * +1 entry, but the recursive path-list is shared.
1427 */
1428 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001429 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001430 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001431 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001432 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001433 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001434
1435 /*
Neale Rannsa0558302017-04-13 00:44:52 -07001436 * An special route; one where the user (me) provides the
1437 * adjacency through which the route will resovle by setting the flags
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001438 */
1439 fib_prefix_t ex_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001440 .fp_len = 32,
1441 .fp_proto = FIB_PROTOCOL_IP4,
1442 .fp_addr = {
1443 /* 4.4.4.4/32 */
1444 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
1445 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001446 };
1447
1448 fib_table_entry_special_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001449 &ex_pfx,
1450 FIB_SOURCE_SPECIAL,
1451 FIB_ENTRY_FLAG_LOCAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001452 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
Neale Rannsa0558302017-04-13 00:44:52 -07001453 dpo = fib_entry_contribute_ip_forwarding(fei);
1454 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
1455 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08001456 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001457
1458 fib_table_entry_special_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001459 &ex_pfx,
1460 FIB_SOURCE_SPECIAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001461 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08001462 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1463 "Exclusive reoute removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001464
1465 /*
1466 * An EXCLUSIVE route; one where the user (me) provides the exclusive
1467 * adjacency through which the route will resovle
1468 */
Neale Ranns948e00f2016-10-20 13:39:34 +01001469 dpo_id_t ex_dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001470
1471 lookup_dpo_add_or_lock_w_fib_index(fib_index,
1472 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001473 LOOKUP_UNICAST,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001474 LOOKUP_INPUT_DST_ADDR,
1475 LOOKUP_TABLE_FROM_CONFIG,
1476 &ex_dpo);
1477
1478 fib_table_entry_special_dpo_add(fib_index,
1479 &ex_pfx,
1480 FIB_SOURCE_SPECIAL,
1481 FIB_ENTRY_FLAG_EXCLUSIVE,
1482 &ex_dpo);
1483 fei = fib_table_lookup_exact_match(fib_index, &ex_pfx);
1484 dpo = fib_entry_contribute_ip_forwarding(fei);
1485 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001486 "exclusive remote uses lookup DPO");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001487
Neale Ranns948e00f2016-10-20 13:39:34 +01001488 /*
1489 * update the exclusive to use a different DPO
1490 */
Neale Ranns450cd302016-11-09 17:49:42 +00001491 ip_null_dpo_add_and_lock(DPO_PROTO_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08001492 IP_NULL_ACTION_SEND_ICMP_UNREACH,
1493 &ex_dpo);
Neale Ranns948e00f2016-10-20 13:39:34 +01001494 fib_table_entry_special_dpo_update(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001495 &ex_pfx,
1496 FIB_SOURCE_SPECIAL,
1497 FIB_ENTRY_FLAG_EXCLUSIVE,
1498 &ex_dpo);
Neale Ranns948e00f2016-10-20 13:39:34 +01001499 dpo = fib_entry_contribute_ip_forwarding(fei);
1500 FIB_TEST(!dpo_cmp(&ex_dpo, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08001501 "exclusive remote uses now uses NULL DPO");
Neale Ranns948e00f2016-10-20 13:39:34 +01001502
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001503 fib_table_entry_special_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001504 &ex_pfx,
1505 FIB_SOURCE_SPECIAL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001506 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08001507 fib_table_lookup_exact_match(fib_index, &ex_pfx),
1508 "Exclusive reoute removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001509 dpo_reset(&ex_dpo);
1510
1511 /*
1512 * Add a recursive route:
1513 * 200.200.200.200/32 via 1.1.1.2/32 => the via entry is NOT installed.
1514 */
1515 fib_prefix_t bgp_200_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001516 .fp_len = 32,
1517 .fp_proto = FIB_PROTOCOL_IP4,
1518 .fp_addr = {
1519 /* 200.200.200.200/32 */
1520 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c8),
1521 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001522 };
1523 /* via 1.1.1.2 */
1524 fib_prefix_t pfx_1_1_1_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001525 .fp_len = 32,
1526 .fp_proto = FIB_PROTOCOL_IP4,
1527 .fp_addr = {
1528 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
1529 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001530 };
1531
Neale Ranns57b58602017-07-15 07:37:25 -07001532 fei = fib_table_entry_path_add(fib_index,
1533 &bgp_200_pfx,
1534 FIB_SOURCE_API,
1535 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001536 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07001537 &pfx_1_1_1_2_s_32.fp_addr,
1538 ~0, // no index provided.
1539 fib_index, // nexthop in same fib as route
1540 1,
1541 NULL,
1542 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001543
Neale Ranns57b58602017-07-15 07:37:25 -07001544 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
1545 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001546
1547 /*
1548 * the adj should be recursive via drop, since the route resolves via
Neale Ranns2303cb12018-02-21 04:57:17 -08001549 * the default route, which is itself a DROP
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001550 */
1551 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
1552 dpo1 = fib_entry_contribute_ip_forwarding(fei);
1553 FIB_TEST(load_balance_is_drop(dpo1), "1.1.1.2/32 is drop");
Neale Ranns2303cb12018-02-21 04:57:17 -08001554 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
1555 "RPF list for 1.1.1.2/32 contains 0 adjs");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001556
1557 /*
1558 * +2 entry and +1 shared-path-list
1559 */
1560 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001561 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001562 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001563 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001564 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08001565 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001566
1567 /*
1568 * Unequal Cost load-balance. 3:1 ratio. fits in a 4 bucket LB
Neale Ranns3ee44042016-10-03 13:05:48 +01001569 * The paths are sort by NH first. in this case the the path with greater
1570 * weight is first in the set. This ordering is to test the RPF sort|uniq logic
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001571 */
1572 fib_prefix_t pfx_1_2_3_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001573 .fp_len = 32,
1574 .fp_proto = FIB_PROTOCOL_IP4,
1575 .fp_addr = {
1576 .ip4.as_u32 = clib_host_to_net_u32(0x01020304),
1577 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001578 };
1579 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001580 &pfx_1_2_3_4_s_32,
1581 FIB_SOURCE_API,
1582 FIB_ENTRY_FLAG_NONE,
1583 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001584 &nh_10_10_10_1,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001585 tm->hw[0]->sw_if_index,
1586 ~0,
1587 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001588 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001589 FIB_ROUTE_PATH_FLAG_NONE);
1590 fei = fib_table_entry_path_add(fib_index,
1591 &pfx_1_2_3_4_s_32,
1592 FIB_SOURCE_API,
1593 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001594 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001595 &nh_12_12_12_12,
1596 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001597 ~0,
1598 3,
Neale Rannsad422ed2016-11-02 14:20:04 +00001599 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001600 FIB_ROUTE_PATH_FLAG_NONE);
1601
1602 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.4/32 presnet");
1603 dpo = fib_entry_contribute_ip_forwarding(fei);
1604 lb = load_balance_get(dpo->dpoi_index);
1605 FIB_TEST((lb->lb_n_buckets == 4),
1606 "1.2.3.4/32 LB has %d bucket",
1607 lb->lb_n_buckets);
1608
Neale Ranns3ee44042016-10-03 13:05:48 +01001609 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 0, ai_12_12_12_12);
1610 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 1, ai_12_12_12_12);
1611 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 2, ai_12_12_12_12);
1612 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_4_s_32, 3, ai_01);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001613
Neale Ranns2303cb12018-02-21 04:57:17 -08001614 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1615 tm->hw[0]->sw_if_index,
1616 tm->hw[1]->sw_if_index),
1617 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01001618
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001619
1620 /*
1621 * Unequal Cost load-balance. 4:1 ratio.
1622 * fits in a 16 bucket LB with ratio 13:3
1623 */
1624 fib_prefix_t pfx_1_2_3_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001625 .fp_len = 32,
1626 .fp_proto = FIB_PROTOCOL_IP4,
1627 .fp_addr = {
1628 .ip4.as_u32 = clib_host_to_net_u32(0x01020305),
1629 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001630 };
1631 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001632 &pfx_1_2_3_5_s_32,
1633 FIB_SOURCE_API,
1634 FIB_ENTRY_FLAG_NONE,
1635 DPO_PROTO_IP4,
Neale Ranns3ee44042016-10-03 13:05:48 +01001636 &nh_12_12_12_12,
1637 tm->hw[1]->sw_if_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001638 ~0,
1639 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00001640 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001641 FIB_ROUTE_PATH_FLAG_NONE);
1642 fei = fib_table_entry_path_add(fib_index,
1643 &pfx_1_2_3_5_s_32,
1644 FIB_SOURCE_API,
1645 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08001646 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001647 &nh_10_10_10_1,
1648 tm->hw[0]->sw_if_index,
1649 ~0,
1650 4,
Neale Rannsad422ed2016-11-02 14:20:04 +00001651 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01001652 FIB_ROUTE_PATH_FLAG_NONE);
1653
1654 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.2.3.5/32 presnet");
1655 dpo = fib_entry_contribute_ip_forwarding(fei);
1656 lb = load_balance_get(dpo->dpoi_index);
1657 FIB_TEST((lb->lb_n_buckets == 16),
1658 "1.2.3.5/32 LB has %d bucket",
1659 lb->lb_n_buckets);
1660
1661 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 0, ai_01);
1662 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 1, ai_01);
1663 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 2, ai_01);
1664 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 3, ai_01);
1665 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 4, ai_01);
1666 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 5, ai_01);
1667 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 6, ai_01);
1668 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 7, ai_01);
1669 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 8, ai_01);
1670 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 9, ai_01);
1671 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 10, ai_01);
1672 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 11, ai_01);
1673 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 12, ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01001674 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 13, ai_12_12_12_12);
1675 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 14, ai_12_12_12_12);
1676 FIB_TEST_LB_BUCKET_VIA_ADJ(&pfx_1_2_3_5_s_32, 15, ai_12_12_12_12);
1677
Neale Ranns2303cb12018-02-21 04:57:17 -08001678 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
1679 tm->hw[0]->sw_if_index,
1680 tm->hw[1]->sw_if_index),
1681 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01001682
1683 /*
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001684 * Test UCMP with a large weight skew - this produces load-balance objects with large
1685 * numbers of buckets to accommodate the skew. By updating said load-balances we are
1686 * laso testing the LB in placce modify code when number of buckets is large.
1687 */
1688 fib_prefix_t pfx_6_6_6_6_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001689 .fp_len = 32,
1690 .fp_proto = FIB_PROTOCOL_IP4,
1691 .fp_addr = {
1692 /* 1.1.1.1/32 */
1693 .ip4.as_u32 = clib_host_to_net_u32(0x06060606),
1694 },
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001695 };
Neale Ranns81424992017-05-18 03:03:22 -07001696 fib_test_lb_bucket_t ip_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08001697 .type = FT_LB_ADJ,
1698 .adj = {
1699 .adj = ai_01,
1700 },
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001701 };
Neale Ranns81424992017-05-18 03:03:22 -07001702 fib_test_lb_bucket_t ip_o_10_10_10_2 = {
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001703 .type = FT_LB_ADJ,
1704 .adj = {
1705 .adj = ai_02,
1706 },
1707 };
1708 fib_test_lb_bucket_t ip_6_6_6_6_o_12_12_12_12 = {
1709 .type = FT_LB_ADJ,
1710 .adj = {
1711 .adj = ai_12_12_12_12,
1712 },
1713 };
1714 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08001715 &pfx_6_6_6_6_s_32,
1716 FIB_SOURCE_API,
1717 FIB_ENTRY_FLAG_NONE,
1718 DPO_PROTO_IP4,
1719 &nh_10_10_10_1,
1720 tm->hw[0]->sw_if_index,
1721 ~0, // invalid fib index
1722 0, // zero weigth
1723 NULL,
1724 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001725
1726 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001727 FIB_TEST(!fib_test_validate_entry(fei,
1728 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1729 1,
1730 &ip_o_10_10_10_1),
1731 "6.6.6.6/32 via 10.10.10.1");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001732
1733 fib_table_entry_path_add(fib_index,
1734 &pfx_6_6_6_6_s_32,
1735 FIB_SOURCE_API,
1736 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001737 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001738 &nh_10_10_10_2,
1739 tm->hw[0]->sw_if_index,
1740 ~0, // invalid fib index
1741 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001742 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001743 FIB_ROUTE_PATH_FLAG_NONE);
1744
1745 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001746 FIB_TEST(!fib_test_validate_entry(fei,
1747 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1748 64,
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_2,
1810 &ip_o_10_10_10_2,
1811 &ip_o_10_10_10_2,
1812 &ip_o_10_10_10_1),
1813 "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 +00001814
1815 fib_table_entry_path_add(fib_index,
1816 &pfx_6_6_6_6_s_32,
1817 FIB_SOURCE_API,
1818 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07001819 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001820 &nh_12_12_12_12,
1821 tm->hw[1]->sw_if_index,
1822 ~0, // invalid fib index
1823 100,
Neale Rannsad422ed2016-11-02 14:20:04 +00001824 NULL,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001825 FIB_ROUTE_PATH_FLAG_NONE);
1826
1827 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001828 FIB_TEST(!fib_test_validate_entry(fei,
1829 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1830 128,
1831 &ip_o_10_10_10_1,
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_o_10_10_10_2,
1894 &ip_o_10_10_10_2,
1895 &ip_o_10_10_10_2,
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 &ip_6_6_6_6_o_12_12_12_12,
1957 &ip_6_6_6_6_o_12_12_12_12,
1958 &ip_6_6_6_6_o_12_12_12_12),
1959 "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 +00001960
1961 fib_table_entry_path_remove(fib_index,
1962 &pfx_6_6_6_6_s_32,
1963 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07001964 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00001965 &nh_12_12_12_12,
1966 tm->hw[1]->sw_if_index,
1967 ~0, // invalid fib index
1968 100,
1969 FIB_ROUTE_PATH_FLAG_NONE);
1970
1971 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08001972 FIB_TEST(!fib_test_validate_entry(fei,
1973 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
1974 64,
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_2,
2036 &ip_o_10_10_10_2,
2037 &ip_o_10_10_10_2,
2038 &ip_o_10_10_10_1),
2039 "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 +00002040
2041 fib_table_entry_path_remove(fib_index,
2042 &pfx_6_6_6_6_s_32,
2043 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002044 DPO_PROTO_IP4,
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002045 &nh_10_10_10_2,
2046 tm->hw[0]->sw_if_index,
2047 ~0, // invalid fib index
2048 100,
2049 FIB_ROUTE_PATH_FLAG_NONE);
2050
2051 fei = fib_table_lookup(fib_index, &pfx_6_6_6_6_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08002052 FIB_TEST(!fib_test_validate_entry(fei,
2053 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
2054 1,
2055 &ip_o_10_10_10_1),
2056 "6.6.6.6/32 via 10.10.10.1");
Neale Ranns0bd36ea2016-11-16 11:47:44 +00002057
2058 fib_table_entry_delete(fib_index, &pfx_6_6_6_6_s_32, FIB_SOURCE_API);
2059
2060 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01002061 * A recursive via the two unequal cost entries
2062 */
2063 fib_prefix_t bgp_44_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002064 .fp_len = 32,
2065 .fp_proto = FIB_PROTOCOL_IP4,
2066 .fp_addr = {
2067 /* 200.200.200.201/32 */
2068 .ip4.as_u32 = clib_host_to_net_u32(0x44444444),
2069 },
Neale Ranns3ee44042016-10-03 13:05:48 +01002070 };
2071 fei = fib_table_entry_path_add(fib_index,
2072 &bgp_44_s_32,
2073 FIB_SOURCE_API,
2074 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08002075 DPO_PROTO_IP4,
2076 &pfx_1_2_3_4_s_32.fp_addr,
Neale Ranns3ee44042016-10-03 13:05:48 +01002077 ~0,
2078 fib_index,
2079 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002080 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002081 FIB_ROUTE_PATH_FLAG_NONE);
2082 fei = fib_table_entry_path_add(fib_index,
2083 &bgp_44_s_32,
2084 FIB_SOURCE_API,
2085 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08002086 DPO_PROTO_IP4,
2087 &pfx_1_2_3_5_s_32.fp_addr,
Neale Ranns3ee44042016-10-03 13:05:48 +01002088 ~0,
2089 fib_index,
2090 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00002091 NULL,
Neale Ranns3ee44042016-10-03 13:05:48 +01002092 FIB_ROUTE_PATH_FLAG_NONE);
2093
2094 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_4_s_32, 0);
2095 FIB_TEST_REC_FORW(&bgp_44_s_32, &pfx_1_2_3_5_s_32, 1);
Neale Ranns2303cb12018-02-21 04:57:17 -08002096 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 2,
2097 tm->hw[0]->sw_if_index,
2098 tm->hw[1]->sw_if_index),
2099 "RPF list for 1.2.3.4/32 contains both adjs");
Neale Ranns3ee44042016-10-03 13:05:48 +01002100
2101 /*
2102 * test the uRPF check functions
2103 */
Neale Ranns948e00f2016-10-20 13:39:34 +01002104 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01002105 index_t urpfi;
2106
2107 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
2108 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
2109
2110 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->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[0]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01002113 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002114 "uRPF check for 68.68.68.68/32 on %d OK",
2115 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01002116 FIB_TEST(!fib_urpf_check(urpfi, 99),
Neale Ranns2303cb12018-02-21 04:57:17 -08002117 "uRPF check for 68.68.68.68/32 on 99 not-OK",
2118 99);
Neale Ranns3ee44042016-10-03 13:05:48 +01002119 dpo_reset(&dpo_44);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002120
2121 fib_table_entry_delete(fib_index,
Neale Ranns3ee44042016-10-03 13:05:48 +01002122 &bgp_44_s_32,
2123 FIB_SOURCE_API);
2124 fib_table_entry_delete(fib_index,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002125 &pfx_1_2_3_5_s_32,
2126 FIB_SOURCE_API);
Neale Ranns3ee44042016-10-03 13:05:48 +01002127 fib_table_entry_delete(fib_index,
2128 &pfx_1_2_3_4_s_32,
2129 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002130
2131 /*
2132 * Add a recursive route:
2133 * 200.200.200.201/32 via 1.1.1.200/32 => the via entry is NOT installed.
2134 */
2135 fib_prefix_t bgp_201_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002136 .fp_len = 32,
2137 .fp_proto = FIB_PROTOCOL_IP4,
2138 .fp_addr = {
2139 /* 200.200.200.201/32 */
2140 .ip4.as_u32 = clib_host_to_net_u32(0xc8c8c8c9),
2141 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002142 };
2143 /* via 1.1.1.200 */
2144 fib_prefix_t pfx_1_1_1_200_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002145 .fp_len = 32,
2146 .fp_proto = FIB_PROTOCOL_IP4,
2147 .fp_addr = {
2148 .ip4.as_u32 = clib_host_to_net_u32(0x010101c8),
2149 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002150 };
2151
Neale Ranns57b58602017-07-15 07:37:25 -07002152 fei = fib_table_entry_path_add(fib_index,
2153 &bgp_201_pfx,
2154 FIB_SOURCE_API,
2155 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002156 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002157 &pfx_1_1_1_200_s_32.fp_addr,
2158 ~0, // no index provided.
2159 fib_index, // nexthop in same fib as route
2160 1,
2161 NULL,
2162 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002163
Neale Ranns57b58602017-07-15 07:37:25 -07002164 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2165 "Recursive via unresolved is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002166
2167 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
2168 FIB_TEST((FIB_ENTRY_FLAG_NONE == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002169 "Flags set on RR via non-attached");
2170 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
2171 "RPF list for BGP route empty");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002172
2173 /*
2174 * +2 entry (BGP & RR) and +1 shared-path-list
2175 */
2176 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002177 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002178 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002179 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002180 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002181 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002182
2183 /*
2184 * insert a route that covers the missing 1.1.1.2/32. we epxect
2185 * 200.200.200.200/32 and 200.200.200.201/32 to resolve through it.
2186 */
2187 fib_prefix_t pfx_1_1_1_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002188 .fp_len = 24,
2189 .fp_proto = FIB_PROTOCOL_IP4,
2190 .fp_addr = {
2191 /* 1.1.1.0/24 */
2192 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2193 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002194 };
2195
2196 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002197 &pfx_1_1_1_0_s_24,
2198 FIB_SOURCE_API,
2199 FIB_ENTRY_FLAG_NONE,
2200 DPO_PROTO_IP4,
2201 &nh_10_10_10_1,
2202 tm->hw[0]->sw_if_index,
2203 ~0, // invalid fib index
2204 1,
2205 NULL,
2206 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002207 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24);
2208 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2209 ai = fib_entry_get_adj(fei);
2210 FIB_TEST((ai_01 == ai), "1.1.1.0/24 resolves via 10.10.10.1");
2211 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2212 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2213 ai = fib_entry_get_adj(fei);
2214 FIB_TEST((ai_01 == ai), "1.1.1.2/32 resolves via 10.10.10.1");
2215 fei = fib_table_lookup(fib_index, &pfx_1_1_1_200_s_32);
2216 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2217 ai = fib_entry_get_adj(fei);
2218 FIB_TEST((ai_01 == ai), "1.1.1.200/24 resolves via 10.10.10.1");
2219
2220 /*
2221 * +1 entry. 1.1.1.1/32 already uses 10.10.10.1 so no new pah-list
2222 */
2223 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002224 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002225 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002226 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002227 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002228 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002229
2230 /*
2231 * the recursive adj for 200.200.200.200 should be updated.
2232 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002233 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2234 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
2235 fei = fib_table_lookup(fib_index, &bgp_200_pfx);
Neale Ranns2303cb12018-02-21 04:57:17 -08002236 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1,
2237 tm->hw[0]->sw_if_index),
2238 "RPF list for BGP route has itf index 0");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002239
2240 /*
2241 * insert a more specific route than 1.1.1.0/24 that also covers the
Neale Ranns2303cb12018-02-21 04:57:17 -08002242 * missing 1.1.1.2/32, but not 1.1.1.200/32. we expect
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002243 * 200.200.200.200 to resolve through it.
2244 */
2245 fib_prefix_t pfx_1_1_1_0_s_28 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002246 .fp_len = 28,
2247 .fp_proto = FIB_PROTOCOL_IP4,
2248 .fp_addr = {
2249 /* 1.1.1.0/24 */
2250 .ip4.as_u32 = clib_host_to_net_u32(0x01010100),
2251 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002252 };
2253
2254 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002255 &pfx_1_1_1_0_s_28,
2256 FIB_SOURCE_API,
2257 FIB_ENTRY_FLAG_NONE,
2258 DPO_PROTO_IP4,
2259 &nh_10_10_10_2,
2260 tm->hw[0]->sw_if_index,
2261 ~0, // invalid fib index
2262 1,
2263 NULL,
2264 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002265 fei = fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28);
2266 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2267 ai = fib_entry_get_adj(fei);
2268 FIB_TEST((ai_02 == ai), "1.1.1.0/24 resolves via 10.10.10.2");
2269
2270 /*
2271 * +1 entry. +1 shared path-list
2272 */
2273 FIB_TEST((5 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002274 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002275 FIB_TEST((PNBR+9 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002276 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002277 FIB_TEST((ENBR+14 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002278 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002279
2280 /*
2281 * the recursive adj for 200.200.200.200 should be updated.
2282 * 200.200.200.201 remains unchanged.
2283 */
Neale Ranns3ee44042016-10-03 13:05:48 +01002284 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2285 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002286
2287 /*
2288 * remove this /28. 200.200.200.200/32 should revert back to via 1.1.1.0/24
2289 */
2290 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002291 &pfx_1_1_1_0_s_28,
2292 FIB_SOURCE_API,
2293 DPO_PROTO_IP4,
2294 &nh_10_10_10_2,
2295 tm->hw[0]->sw_if_index,
2296 ~0,
2297 1,
2298 FIB_ROUTE_PATH_FLAG_NONE);
2299 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28) ==
2300 FIB_NODE_INDEX_INVALID),
2301 "1.1.1.0/28 removed");
2302 FIB_TEST((fib_table_lookup(fib_index, &pfx_1_1_1_0_s_28) ==
2303 fib_table_lookup(fib_index, &pfx_1_1_1_0_s_24)),
2304 "1.1.1.0/28 lookup via /24");
Neale Ranns3ee44042016-10-03 13:05:48 +01002305 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_200_s_32, 0);
2306 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002307
2308 /*
2309 * -1 entry. -1 shared path-list
2310 */
2311 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002312 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002313 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002314 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002315 FIB_TEST((ENBR+13 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002316 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002317
2318 /*
2319 * remove 1.1.1.0/24. 200.200.200.200/32 should revert back to via 0.0.0.0/0
2320 */
2321 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002322 &pfx_1_1_1_0_s_24,
2323 FIB_SOURCE_API,
2324 DPO_PROTO_IP4,
2325 &nh_10_10_10_1,
2326 tm->hw[0]->sw_if_index,
2327 ~0,
2328 1,
2329 FIB_ROUTE_PATH_FLAG_NONE);
2330 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_24) ==
2331 FIB_NODE_INDEX_INVALID),
2332 "1.1.1.0/24 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002333
2334 fei = fib_table_lookup(fib_index, &pfx_1_1_1_2_s_32);
2335 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002336 "1.1.1.2/32 route is DROP");
Neale Ranns57b58602017-07-15 07:37:25 -07002337 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002338 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002339 "1.1.1.200/32 route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002340
Neale Ranns57b58602017-07-15 07:37:25 -07002341 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2342 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2343 "201 is drop");
2344 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2345 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2346 "200 is drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002347
2348 /*
2349 * -1 entry
2350 */
2351 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002352 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002353 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002354 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002355 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002356 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002357
2358 /*
2359 * insert the missing 1.1.1.2/32
2360 */
2361 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002362 &pfx_1_1_1_2_s_32,
2363 FIB_SOURCE_API,
2364 FIB_ENTRY_FLAG_NONE,
2365 DPO_PROTO_IP4,
2366 &nh_10_10_10_1,
2367 tm->hw[0]->sw_if_index,
2368 ~0, // invalid fib index
2369 1,
2370 NULL,
2371 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002372 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2373 ai = fib_entry_get_adj(fei);
2374 FIB_TEST((ai = ai_01), "1.1.1.2/32 resolves via 10.10.10.1");
2375
Neale Ranns57b58602017-07-15 07:37:25 -07002376 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2377 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
2378 "201 is drop");
Neale Ranns3ee44042016-10-03 13:05:48 +01002379 FIB_TEST_REC_FORW(&bgp_200_pfx, &pfx_1_1_1_2_s_32, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002380
2381 /*
2382 * no change. 1.1.1.2/32 was already there RR sourced.
2383 */
2384 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002385 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002386 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002387 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002388 FIB_TEST((ENBR+12 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002389 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002390
2391 /*
Neale Ranns57b58602017-07-15 07:37:25 -07002392 * give 201 a resolved path.
2393 * it now has the unresolved 1.1.1.200 and the resolved 1.1.1.2,
2394 * only the latter contributes forwarding.
2395 */
2396 fei = fib_table_entry_path_add(fib_index,
2397 &bgp_201_pfx,
2398 FIB_SOURCE_API,
2399 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07002400 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002401 &pfx_1_1_1_2_s_32.fp_addr,
2402 ~0,
2403 fib_index,
2404 1,
2405 NULL,
2406 FIB_ROUTE_PATH_FLAG_NONE);
2407 FIB_TEST_REC_FORW(&bgp_201_pfx, &pfx_1_1_1_2_s_32, 0);
2408 fib_table_entry_path_remove(fib_index,
2409 &bgp_201_pfx,
2410 FIB_SOURCE_API,
Neale Rannsda78f952017-05-24 09:15:43 -07002411 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07002412 &pfx_1_1_1_2_s_32.fp_addr,
2413 ~0,
2414 fib_index,
2415 1,
2416 FIB_ROUTE_PATH_FLAG_NONE);
2417
2418 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002419 * remove 200.200.200.201/32 which does not have a valid via FIB
2420 */
2421 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002422 &bgp_201_pfx,
2423 FIB_SOURCE_API,
2424 DPO_PROTO_IP4,
2425 &pfx_1_1_1_200_s_32.fp_addr,
2426 ~0, // no index provided.
2427 fib_index,
2428 1,
2429 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002430
2431 /*
2432 * -2 entries (BGP and RR). -1 shared path-list;
2433 */
Neale Ranns2303cb12018-02-21 04:57:17 -08002434 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
2435 FIB_NODE_INDEX_INVALID),
2436 "200.200.200.201/32 removed");
2437 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_200_s_32) ==
2438 FIB_NODE_INDEX_INVALID),
2439 "1.1.1.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002440
2441 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002442 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002443 FIB_TEST((PNBR+7 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002444 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002445 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002446 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002447
2448 /*
2449 * remove 200.200.200.200/32 which does have a valid via FIB
2450 */
2451 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002452 &bgp_200_pfx,
2453 FIB_SOURCE_API,
2454 DPO_PROTO_IP4,
2455 &pfx_1_1_1_2_s_32.fp_addr,
2456 ~0, // no index provided.
2457 fib_index,
2458 1,
2459 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002460
Neale Ranns2303cb12018-02-21 04:57:17 -08002461 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
2462 FIB_NODE_INDEX_INVALID),
2463 "200.200.200.200/32 removed");
2464 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32) !=
2465 FIB_NODE_INDEX_INVALID),
2466 "1.1.1.2/32 still present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002467
2468 /*
2469 * -1 entry (BGP, the RR source is also API sourced). -1 shared path-list;
2470 */
2471 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002472 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002473 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002474 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002475 FIB_TEST((ENBR+9 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002476 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002477
2478 /*
2479 * A recursive prefix that has a 2 path load-balance.
2480 * It also shares a next-hop with other BGP prefixes and hence
2481 * test the ref counting of RR sourced prefixes and 2 level LB.
2482 */
2483 const fib_prefix_t bgp_102 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002484 .fp_len = 32,
2485 .fp_proto = FIB_PROTOCOL_IP4,
2486 .fp_addr = {
2487 /* 100.100.100.101/32 */
2488 .ip4.as_u32 = clib_host_to_net_u32(0x64646466),
2489 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002490 };
2491 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002492 &bgp_102,
2493 FIB_SOURCE_API,
2494 FIB_ENTRY_FLAG_NONE,
2495 DPO_PROTO_IP4,
2496 &pfx_1_1_1_1_s_32.fp_addr,
2497 ~0, // no index provided.
2498 fib_index, // same as route
2499 1,
2500 NULL,
2501 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002502 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002503 &bgp_102,
2504 FIB_SOURCE_API,
2505 FIB_ENTRY_FLAG_NONE,
2506 DPO_PROTO_IP4,
2507 &pfx_1_1_1_2_s_32.fp_addr,
2508 ~0, // no index provided.
2509 fib_index, // same as route's FIB
2510 1,
2511 NULL,
2512 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002513 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2514 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "100.100.100.102/32 presnet");
2515 dpo = fib_entry_contribute_ip_forwarding(fei);
2516
2517 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
2518 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2519 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_2_s_32);
2520 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2521
2522 lb = load_balance_get(dpo->dpoi_index);
2523 FIB_TEST((lb->lb_n_buckets == 2), "Recursive LB has %d bucket", lb->lb_n_buckets);
2524 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002525 "First via 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002526 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002527 "Second via 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002528
2529 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002530 &bgp_102,
2531 FIB_SOURCE_API,
2532 DPO_PROTO_IP4,
2533 &pfx_1_1_1_1_s_32.fp_addr,
2534 ~0, // no index provided.
2535 fib_index, // same as route's FIB
2536 1,
2537 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002538 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002539 &bgp_102,
2540 FIB_SOURCE_API,
2541 DPO_PROTO_IP4,
2542 &pfx_1_1_1_2_s_32.fp_addr,
2543 ~0, // no index provided.
2544 fib_index, // same as route's FIB
2545 1,
2546 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002547 fei = fib_table_lookup_exact_match(fib_index, &bgp_102);
2548 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "100.100.100.102/32 removed");
2549
2550 /*
2551 * remove the remaining recursives
2552 */
2553 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002554 &bgp_100_pfx,
2555 FIB_SOURCE_API,
2556 DPO_PROTO_IP4,
2557 &pfx_1_1_1_1_s_32.fp_addr,
2558 ~0, // no index provided.
2559 fib_index, // same as route's FIB
2560 1,
2561 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002562 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002563 &bgp_101_pfx,
2564 FIB_SOURCE_API,
2565 DPO_PROTO_IP4,
2566 &pfx_1_1_1_1_s_32.fp_addr,
2567 ~0, // no index provided.
2568 fib_index, // same as route's FIB
2569 1,
2570 FIB_ROUTE_PATH_FLAG_NONE);
2571 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_100_pfx) ==
2572 FIB_NODE_INDEX_INVALID),
2573 "100.100.100.100/32 removed");
2574 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_101_pfx) ==
2575 FIB_NODE_INDEX_INVALID),
2576 "100.100.100.101/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002577
2578 /*
2579 * -2 entry (2*BGP, the RR source is also API sourced). -1 shared path-list;
2580 */
2581 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002582 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002583 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002584 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002585 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002586 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002587
2588 /*
2589 * Add a recursive route via a connected cover, using an adj-fib that does exist
2590 */
2591 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002592 &bgp_200_pfx,
2593 FIB_SOURCE_API,
2594 FIB_ENTRY_FLAG_NONE,
2595 DPO_PROTO_IP4,
2596 &nh_10_10_10_1,
2597 ~0, // no index provided.
2598 fib_index, // Same as route's FIB
2599 1,
2600 NULL,
2601 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002602
2603 /*
2604 * +1 entry. +1 shared path-list (recursive via 10.10.10.1)
2605 */
2606 FIB_TEST((2 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002607 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002608 FIB_TEST((PNBR+6 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002609 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002610 FIB_TEST((ENBR+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002611 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002612
2613 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
2614 dpo = fib_entry_contribute_ip_forwarding(fei);
2615
2616 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
2617 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2618
2619 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002620 "200.200.200.200/32 is recursive via adj for 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002621
2622 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED == fib_entry_get_flags(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002623 "Flags set on RR via existing attached");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002624
2625 /*
2626 * Add a recursive route via a connected cover, using and adj-fib that does
2627 * not exist
2628 */
2629 ip46_address_t nh_10_10_10_3 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002630 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002631 };
2632 fib_prefix_t pfx_10_10_10_3 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002633 .fp_len = 32,
2634 .fp_proto = FIB_PROTOCOL_IP4,
2635 .fp_addr = nh_10_10_10_3,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002636 };
2637
2638 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002639 &bgp_201_pfx,
2640 FIB_SOURCE_API,
2641 FIB_ENTRY_FLAG_NONE,
2642 DPO_PROTO_IP4,
2643 &nh_10_10_10_3,
2644 ~0, // no index provided.
2645 fib_index,
2646 1,
2647 NULL,
2648 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002649
2650 /*
2651 * +2 entries (BGP and RR). +1 shared path-list (recursive via 10.10.10.3) and
2652 * one unshared non-recursive via 10.10.10.3
2653 */
2654 FIB_TEST((3 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002655 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002656 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002657 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002658 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002659 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002660
2661 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08002662 VNET_LINK_IP4,
2663 &nh_10_10_10_3,
2664 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002665
2666 fei = fib_table_lookup_exact_match(fib_index, &bgp_201_pfx);
2667 dpo = fib_entry_contribute_ip_forwarding(fei);
2668 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3);
2669 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2670
2671 ai = fib_entry_get_adj(fei);
2672 FIB_TEST((ai == ai_03), "adj for 10.10.10.3/32 is via adj for 10.10.10.3");
2673 FIB_TEST(((FIB_ENTRY_FLAG_ATTACHED | FIB_ENTRY_FLAG_CONNECTED) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002674 fib_entry_get_flags(fei)),
2675 "Flags set on RR via non-existing attached");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002676
2677 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002678 "adj for 200.200.200.200/32 is recursive via adj for 10.10.10.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002679
2680 adj_unlock(ai_03);
2681
2682 /*
2683 * remove the recursives
2684 */
2685 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002686 &bgp_200_pfx,
2687 FIB_SOURCE_API,
2688 DPO_PROTO_IP4,
2689 &nh_10_10_10_1,
2690 ~0, // no index provided.
2691 fib_index, // same as route's FIB
2692 1,
2693 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002694 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002695 &bgp_201_pfx,
2696 FIB_SOURCE_API,
2697 DPO_PROTO_IP4,
2698 &nh_10_10_10_3,
2699 ~0, // no index provided.
2700 fib_index, // same as route's FIB
2701 1,
2702 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002703
2704 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_201_pfx) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002705 FIB_NODE_INDEX_INVALID),
2706 "200.200.200.201/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002707 FIB_TEST((fib_table_lookup_exact_match(fib_index, &bgp_200_pfx) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002708 FIB_NODE_INDEX_INVALID),
2709 "200.200.200.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002710 FIB_TEST((fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3) ==
Neale Ranns2303cb12018-02-21 04:57:17 -08002711 FIB_NODE_INDEX_INVALID),
2712 "10.10.10.3/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002713
2714 /*
2715 * -3 entries (2*BGP and RR). -2 shared path-list (recursive via 10.10.10.3 &
2716 * 10.10.10.1) and one unshared non-recursive via 10.10.10.3
2717 */
2718 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002719 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002720 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002721 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002722 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002723 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002724
2725
2726 /*
2727 * RECURSION LOOPS
2728 * Add 5.5.5.5/32 -> 5.5.5.6/32 -> 5.5.5.7/32 -> 5.5.5.5/32
2729 */
2730 fib_prefix_t pfx_5_5_5_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002731 .fp_len = 32,
2732 .fp_proto = FIB_PROTOCOL_IP4,
2733 .fp_addr = {
2734 .ip4.as_u32 = clib_host_to_net_u32(0x05050505),
2735 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002736 };
2737 fib_prefix_t pfx_5_5_5_6_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002738 .fp_len = 32,
2739 .fp_proto = FIB_PROTOCOL_IP4,
2740 .fp_addr = {
2741 .ip4.as_u32 = clib_host_to_net_u32(0x05050506),
2742 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002743 };
2744 fib_prefix_t pfx_5_5_5_7_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08002745 .fp_len = 32,
2746 .fp_proto = FIB_PROTOCOL_IP4,
2747 .fp_addr = {
2748 .ip4.as_u32 = clib_host_to_net_u32(0x05050507),
2749 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002750 };
2751
2752 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002753 &pfx_5_5_5_5_s_32,
2754 FIB_SOURCE_API,
2755 FIB_ENTRY_FLAG_NONE,
2756 DPO_PROTO_IP4,
2757 &pfx_5_5_5_6_s_32.fp_addr,
2758 ~0, // no index provided.
2759 fib_index,
2760 1,
2761 NULL,
2762 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002763 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002764 &pfx_5_5_5_6_s_32,
2765 FIB_SOURCE_API,
2766 FIB_ENTRY_FLAG_NONE,
2767 DPO_PROTO_IP4,
2768 &pfx_5_5_5_7_s_32.fp_addr,
2769 ~0, // no index provided.
2770 fib_index,
2771 1,
2772 NULL,
2773 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002774 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002775 &pfx_5_5_5_7_s_32,
2776 FIB_SOURCE_API,
2777 FIB_ENTRY_FLAG_NONE,
2778 DPO_PROTO_IP4,
2779 &pfx_5_5_5_5_s_32.fp_addr,
2780 ~0, // no index provided.
2781 fib_index,
2782 1,
2783 NULL,
2784 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002785 /*
2786 * +3 entries, +3 shared path-list
2787 */
2788 FIB_TEST((4 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002789 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002790 FIB_TEST((PNBR+8 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002791 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002792 FIB_TEST((ENBR+10 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002793 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002794
2795 /*
2796 * All the entries have only looped paths, so they are all drop
2797 */
2798 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_s_32);
2799 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002800 "LB for 5.5.5.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002801 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2802 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002803 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002804 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2805 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002806 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002807
2808 /*
2809 * provide 5.5.5.6/32 with alternate path.
2810 * this will allow only 5.5.5.6/32 to forward with this path, the others
2811 * are still drop since the loop is still present.
2812 */
2813 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002814 &pfx_5_5_5_6_s_32,
2815 FIB_SOURCE_API,
2816 FIB_ENTRY_FLAG_NONE,
2817 DPO_PROTO_IP4,
2818 &nh_10_10_10_1,
2819 tm->hw[0]->sw_if_index,
2820 ~0,
2821 1,
2822 NULL,
2823 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002824
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002825 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2826 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2827
2828 lb = load_balance_get(dpo1->dpoi_index);
2829 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.6 LB has %d bucket", lb->lb_n_buckets);
2830
2831 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2832 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2833 FIB_TEST((ai_01 == dpo2->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002834 "5.5.5.6 bucket 0 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002835
2836 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_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.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002839 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2840 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002841 "LB for 5.5.5.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002842
2843 /*
2844 * remove the alternate path for 5.5.5.6/32
2845 * back to all drop
2846 */
2847 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002848 &pfx_5_5_5_6_s_32,
2849 FIB_SOURCE_API,
2850 DPO_PROTO_IP4,
2851 &nh_10_10_10_1,
2852 tm->hw[0]->sw_if_index,
2853 ~0,
2854 1,
2855 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002856
2857 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_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.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002860 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_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.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002863 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2864 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002865 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002866
2867 /*
2868 * break the loop by giving 5.5.5.5/32 a new set of paths
2869 * expect all to forward via this new path.
2870 */
2871 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002872 &pfx_5_5_5_5_s_32,
2873 FIB_SOURCE_API,
2874 FIB_ENTRY_FLAG_NONE,
2875 DPO_PROTO_IP4,
2876 &nh_10_10_10_1,
2877 tm->hw[0]->sw_if_index,
2878 ~0, // invalid fib index
2879 1,
2880 NULL,
2881 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002882
2883 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_s_32);
2884 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2885 lb = load_balance_get(dpo1->dpoi_index);
2886 FIB_TEST((lb->lb_n_buckets == 1), "5.5.5.5 LB has %d bucket", lb->lb_n_buckets);
2887
2888 dpo2 = load_balance_get_bucket(dpo1->dpoi_index, 0);
2889 FIB_TEST(DPO_ADJACENCY == dpo2->dpoi_type, "type is %d", dpo2->dpoi_type);
2890 FIB_TEST((ai_01 == dpo2->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08002891 "5.5.5.5 bucket 0 resolves via 10.10.10.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002892
2893 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_7_s_32);
2894 dpo2 = fib_entry_contribute_ip_forwarding(fei);
2895
2896 lb = load_balance_get(dpo2->dpoi_index);
2897 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2898 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo2->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002899 "5.5.5.5.7 via 5.5.5.5");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002900
2901 fei = fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32);
2902 dpo1 = fib_entry_contribute_ip_forwarding(fei);
2903
2904 lb = load_balance_get(dpo1->dpoi_index);
2905 FIB_TEST((lb->lb_n_buckets == 1), "Recursive LB has %d bucket", lb->lb_n_buckets);
2906 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002907 "5.5.5.5.6 via 5.5.5.7");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002908
2909 /*
2910 * revert back to the loop. so we can remove the prefixes with
2911 * the loop intact
2912 */
2913 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002914 &pfx_5_5_5_5_s_32,
2915 FIB_SOURCE_API,
2916 FIB_ENTRY_FLAG_NONE,
2917 DPO_PROTO_IP4,
2918 &pfx_5_5_5_6_s_32.fp_addr,
2919 ~0, // no index provided.
2920 fib_index,
2921 1,
2922 NULL,
2923 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002924
2925 fei = fib_table_lookup(fib_index, &pfx_5_5_5_7_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.7/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002928 fei = fib_table_lookup(fib_index, &pfx_5_5_5_5_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.5/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002931 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
2932 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08002933 "LB for 5.5.5.6/32 is via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002934
2935 /*
2936 * remove all the 5.5.5.x/32 prefixes
2937 */
2938 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002939 &pfx_5_5_5_5_s_32,
2940 FIB_SOURCE_API,
2941 DPO_PROTO_IP4,
2942 &pfx_5_5_5_6_s_32.fp_addr,
2943 ~0, // no index provided.
2944 fib_index, // same as route's FIB
2945 1,
2946 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002947 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002948 &pfx_5_5_5_6_s_32,
2949 FIB_SOURCE_API,
2950 DPO_PROTO_IP4,
2951 &pfx_5_5_5_7_s_32.fp_addr,
2952 ~0, // no index provided.
2953 fib_index, // same as route's FIB
2954 1,
2955 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002956 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002957 &pfx_5_5_5_7_s_32,
2958 FIB_SOURCE_API,
2959 DPO_PROTO_IP4,
2960 &pfx_5_5_5_5_s_32.fp_addr,
2961 ~0, // no index provided.
2962 fib_index, // same as route's FIB
2963 1,
2964 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002965 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002966 &pfx_5_5_5_6_s_32,
2967 FIB_SOURCE_API,
2968 DPO_PROTO_IP4,
2969 &nh_10_10_10_2,
2970 ~0, // no index provided.
2971 fib_index, // same as route's FIB
2972 1,
2973 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002974
2975 /*
2976 * -3 entries, -3 shared path-list
2977 */
2978 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002979 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002980 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002981 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00002982 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08002983 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002984
2985 /*
2986 * Single level loop 5.5.5.5/32 via 5.5.5.5/32
2987 */
2988 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08002989 &pfx_5_5_5_6_s_32,
2990 FIB_SOURCE_API,
2991 FIB_ENTRY_FLAG_NONE,
2992 DPO_PROTO_IP4,
2993 &pfx_5_5_5_6_s_32.fp_addr,
2994 ~0, // no index provided.
2995 fib_index,
2996 1,
2997 NULL,
2998 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01002999 fei = fib_table_lookup(fib_index, &pfx_5_5_5_6_s_32);
3000 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003001 "1-level 5.5.5.6/32 loop is via adj for DROP");
3002
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003003 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003004 &pfx_5_5_5_6_s_32,
3005 FIB_SOURCE_API,
3006 DPO_PROTO_IP4,
3007 &pfx_5_5_5_6_s_32.fp_addr,
3008 ~0, // no index provided.
3009 fib_index, // same as route's FIB
3010 1,
3011 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003012 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003013 fib_table_lookup_exact_match(fib_index, &pfx_5_5_5_6_s_32),
3014 "1-level 5.5.5.6/32 loop is removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003015
3016 /*
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003017 * A recursive route whose next-hop is covered by the prefix.
3018 * This would mean the via-fib, which inherits forwarding from its
3019 * cover, thus picks up forwarding from the prfix, which is via the
3020 * via-fib, and we have a loop.
3021 */
3022 fib_prefix_t pfx_23_23_23_0_s_24 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003023 .fp_len = 24,
3024 .fp_proto = FIB_PROTOCOL_IP4,
3025 .fp_addr = {
3026 .ip4.as_u32 = clib_host_to_net_u32(0x17171700),
3027 },
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003028 };
3029 fib_prefix_t pfx_23_23_23_23_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003030 .fp_len = 32,
3031 .fp_proto = FIB_PROTOCOL_IP4,
3032 .fp_addr = {
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003033 .ip4.as_u32 = clib_host_to_net_u32(0x17171717),
3034 },
3035 };
3036 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003037 &pfx_23_23_23_0_s_24,
3038 FIB_SOURCE_API,
3039 FIB_ENTRY_FLAG_NONE,
3040 DPO_PROTO_IP4,
3041 &pfx_23_23_23_23_s_32.fp_addr,
3042 ~0, // recursive
3043 fib_index,
3044 1,
3045 NULL,
3046 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003047 dpo = fib_entry_contribute_ip_forwarding(fei);
3048 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003049 "23.23.23.0/24 via covered is DROP");
Neale Ranns3dffb1e2016-11-01 20:38:53 +00003050 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
3051
3052 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003053 * add-remove test. no change.
3054 */
3055 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003056 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003057 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003058 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003059 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003060 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003061
3062 /*
Neale Ranns08b16482017-05-13 05:52:58 -07003063 * Make the default route recursive via a unknown next-hop. Thus the
3064 * next hop's cover would be the default route
3065 */
3066 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003067 &pfx_0_0_0_0_s_0,
3068 FIB_SOURCE_API,
3069 FIB_ENTRY_FLAG_NONE,
3070 DPO_PROTO_IP4,
3071 &pfx_23_23_23_23_s_32.fp_addr,
3072 ~0, // recursive
3073 fib_index,
3074 1,
3075 NULL,
3076 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns08b16482017-05-13 05:52:58 -07003077 dpo = fib_entry_contribute_ip_forwarding(fei);
3078 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003079 "0.0.0.0.0/0 via is DROP");
Neale Ranns08b16482017-05-13 05:52:58 -07003080 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3081 "no resolving interface for looped 0.0.0.0/0");
3082
3083 fei = fib_table_lookup_exact_match(fib_index, &pfx_23_23_23_23_s_32);
3084 dpo = fib_entry_contribute_ip_forwarding(fei);
3085 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003086 "23.23.23.23/32 via is DROP");
Neale Ranns08b16482017-05-13 05:52:58 -07003087 FIB_TEST((fib_entry_get_resolving_interface(fei) == ~0),
3088 "no resolving interface for looped 23.23.23.23/32");
3089
3090 fib_table_entry_delete(fib_index, &pfx_0_0_0_0_s_0, FIB_SOURCE_API);
3091
3092 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003093 * A recursive route with recursion constraints.
3094 * 200.200.200.200/32 via 1.1.1.1 is recurse via host constrained
3095 */
3096 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003097 &bgp_200_pfx,
3098 FIB_SOURCE_API,
3099 FIB_ENTRY_FLAG_NONE,
3100 DPO_PROTO_IP4,
3101 &nh_1_1_1_1,
3102 ~0,
3103 fib_index,
3104 1,
3105 NULL,
3106 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003107
3108 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3109 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3110
3111 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3112 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3113
3114 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003115 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003116
3117 /*
3118 * save the load-balance. we expect it to be inplace modified
3119 */
3120 lb = load_balance_get(dpo1->dpoi_index);
3121
3122 /*
3123 * add a covering prefix for the via fib that would otherwise serve
3124 * as the resolving route when the host is removed
3125 */
3126 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003127 &pfx_1_1_1_0_s_28,
3128 FIB_SOURCE_API,
3129 FIB_ENTRY_FLAG_NONE,
3130 DPO_PROTO_IP4,
3131 &nh_10_10_10_1,
3132 tm->hw[0]->sw_if_index,
3133 ~0, // invalid fib index
3134 1,
3135 NULL,
3136 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003137 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_0_s_28);
3138 ai = fib_entry_get_adj(fei);
3139 FIB_TEST((ai == ai_01),
Neale Ranns2303cb12018-02-21 04:57:17 -08003140 "adj for 1.1.1.0/28 is via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003141
3142 /*
3143 * remove the host via FIB - expect the BGP prefix to be drop
3144 */
3145 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003146 &pfx_1_1_1_1_s_32,
3147 FIB_SOURCE_API,
3148 DPO_PROTO_IP4,
3149 &nh_10_10_10_1,
3150 tm->hw[0]->sw_if_index,
3151 ~0, // invalid fib index
3152 1,
3153 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003154
3155 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003156 "adj for 200.200.200.200/32 is recursive via adj for DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003157
3158 /*
3159 * add the via-entry host reoute back. expect to resolve again
3160 */
3161 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003162 &pfx_1_1_1_1_s_32,
3163 FIB_SOURCE_API,
3164 FIB_ENTRY_FLAG_NONE,
3165 DPO_PROTO_IP4,
3166 &nh_10_10_10_1,
3167 tm->hw[0]->sw_if_index,
3168 ~0, // invalid fib index
3169 1,
3170 NULL,
3171 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003172 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo1->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003173 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003174
3175 /*
3176 * add another path for the recursive. it will then have 2.
3177 */
3178 fib_prefix_t pfx_1_1_1_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003179 .fp_len = 32,
3180 .fp_proto = FIB_PROTOCOL_IP4,
3181 .fp_addr = {
3182 .ip4.as_u32 = clib_host_to_net_u32(0x01010103),
3183 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003184 };
3185 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003186 &pfx_1_1_1_3_s_32,
3187 FIB_SOURCE_API,
3188 FIB_ENTRY_FLAG_NONE,
3189 DPO_PROTO_IP4,
3190 &nh_10_10_10_2,
3191 tm->hw[0]->sw_if_index,
3192 ~0, // invalid fib index
3193 1,
3194 NULL,
3195 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003196
3197 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003198 &bgp_200_pfx,
3199 FIB_SOURCE_API,
3200 FIB_ENTRY_FLAG_NONE,
3201 DPO_PROTO_IP4,
3202 &pfx_1_1_1_3_s_32.fp_addr,
3203 ~0,
3204 fib_index,
3205 1,
3206 NULL,
3207 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003208
Neale Rannsf12a83f2017-04-18 09:09:40 -07003209 /*
3210 * add a bunch load more entries using this path combo so that we get
3211 * an LB-map created.
3212 */
3213#define N_P 128
3214 fib_prefix_t bgp_78s[N_P];
3215 for (ii = 0; ii < N_P; ii++)
3216 {
3217 bgp_78s[ii].fp_len = 32;
3218 bgp_78s[ii].fp_proto = FIB_PROTOCOL_IP4;
3219 bgp_78s[ii].fp_addr.ip4.as_u32 = clib_host_to_net_u32(0x4e000000+ii);
3220
Neale Ranns2303cb12018-02-21 04:57:17 -08003221
Neale Rannsf12a83f2017-04-18 09:09:40 -07003222 fib_table_entry_path_add(fib_index,
3223 &bgp_78s[ii],
3224 FIB_SOURCE_API,
3225 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003226 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003227 &pfx_1_1_1_3_s_32.fp_addr,
3228 ~0,
3229 fib_index,
3230 1,
3231 NULL,
3232 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3233 fib_table_entry_path_add(fib_index,
3234 &bgp_78s[ii],
3235 FIB_SOURCE_API,
3236 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003237 DPO_PROTO_IP4,
Neale Rannsf12a83f2017-04-18 09:09:40 -07003238 &nh_1_1_1_1,
3239 ~0,
3240 fib_index,
3241 1,
3242 NULL,
3243 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
3244 }
3245
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003246 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3247 dpo = fib_entry_contribute_ip_forwarding(fei);
3248
3249 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_1_s_32);
3250 dpo2 = fib_entry_contribute_ip_forwarding(fei);
3251 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003252 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003253 fei = fib_table_lookup_exact_match(fib_index, &pfx_1_1_1_3_s_32);
3254 dpo1 = fib_entry_contribute_ip_forwarding(fei);
3255 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket(dpo->dpoi_index, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003256 "adj for 200.200.200.200/32 is recursive via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003257
3258 /*
3259 * expect the lb-map used by the recursive's load-balance is using both buckets
3260 */
3261 load_balance_map_t *lbm;
3262 index_t lbmi;
3263
3264 lb = load_balance_get(dpo->dpoi_index);
3265 lbmi = lb->lb_map;
3266 load_balance_map_lock(lbmi);
3267 lbm = load_balance_map_get(lbmi);
3268
3269 FIB_TEST(lbm->lbm_buckets[0] == 0,
3270 "LB maps's bucket 0 is %d",
3271 lbm->lbm_buckets[0]);
3272 FIB_TEST(lbm->lbm_buckets[1] == 1,
3273 "LB maps's bucket 1 is %d",
3274 lbm->lbm_buckets[1]);
3275
3276 /*
3277 * withdraw one of the /32 via-entrys.
3278 * that ECMP path will be unresolved and forwarding should continue on the
3279 * other available path. this is an iBGP PIC edge failover.
3280 * Test the forwarding changes without re-fetching the adj from the
3281 * recursive entry. this ensures its the same one that is updated; i.e. an
3282 * inplace-modify.
3283 */
3284 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003285 &pfx_1_1_1_1_s_32,
3286 FIB_SOURCE_API,
3287 DPO_PROTO_IP4,
3288 &nh_10_10_10_1,
3289 tm->hw[0]->sw_if_index,
3290 ~0, // invalid fib index
3291 1,
3292 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003293
Neale Rannsf12a83f2017-04-18 09:09:40 -07003294 /* suspend so the update walk kicks int */
3295 vlib_process_suspend(vlib_get_main(), 1e-5);
3296
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003297 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3298 FIB_TEST(!dpo_cmp(dpo, fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003299 "post PIC 200.200.200.200/32 was inplace modified");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003300
3301 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003302 "post PIC adj for 200.200.200.200/32 is recursive"
3303 " via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003304
3305 /*
3306 * the LB maps that was locked above should have been modified to remove
3307 * the path that was down, and thus its bucket points to a path that is
3308 * still up.
3309 */
3310 FIB_TEST(lbm->lbm_buckets[0] == 1,
3311 "LB maps's bucket 0 is %d",
3312 lbm->lbm_buckets[0]);
3313 FIB_TEST(lbm->lbm_buckets[1] == 1,
3314 "LB maps's bucket 1 is %d",
3315 lbm->lbm_buckets[1]);
3316
Neale Ranns994dab42017-04-18 12:56:45 -07003317 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003318
3319 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08003320 * add it back. again
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003321 */
3322 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003323 &pfx_1_1_1_1_s_32,
3324 FIB_SOURCE_API,
3325 FIB_ENTRY_FLAG_NONE,
3326 DPO_PROTO_IP4,
3327 &nh_10_10_10_1,
3328 tm->hw[0]->sw_if_index,
3329 ~0, // invalid fib index
3330 1,
3331 NULL,
3332 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003333
Neale Rannsf12a83f2017-04-18 09:09:40 -07003334 /* suspend so the update walk kicks in */
3335 vlib_process_suspend(vlib_get_main(), 1e-5);
3336
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003337 FIB_TEST(!dpo_cmp(dpo2, load_balance_get_bucket_i(lb, 0)),
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.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003340 FIB_TEST(!dpo_cmp(dpo1, load_balance_get_bucket_i(lb, 1)),
Neale Ranns2303cb12018-02-21 04:57:17 -08003341 "post PIC recovery adj for 200.200.200.200/32 is recursive "
3342 "via adj for 1.1.1.3");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003343
3344 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3345 dpo = fib_entry_contribute_ip_forwarding(fei);
3346 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003347 "post PIC 200.200.200.200/32 was inplace modified");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003348
3349 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08003350 * add a 3rd path. this makes the LB 16 buckets.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003351 */
3352 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003353 &bgp_200_pfx,
3354 FIB_SOURCE_API,
3355 FIB_ENTRY_FLAG_NONE,
3356 DPO_PROTO_IP4,
3357 &pfx_1_1_1_2_s_32.fp_addr,
3358 ~0,
3359 fib_index,
3360 1,
3361 NULL,
3362 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003363 for (ii = 0; ii < N_P; ii++)
3364 {
3365 fib_table_entry_path_add(fib_index,
3366 &bgp_78s[ii],
Neale Ranns2303cb12018-02-21 04:57:17 -08003367 FIB_SOURCE_API,
3368 FIB_ENTRY_FLAG_NONE,
3369 DPO_PROTO_IP4,
3370 &pfx_1_1_1_2_s_32.fp_addr,
3371 ~0,
3372 fib_index,
3373 1,
3374 NULL,
3375 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003376 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003377
3378 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3379 dpo = fib_entry_contribute_ip_forwarding(fei);
3380 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003381 "200.200.200.200/32 was inplace modified for 3rd path");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003382 FIB_TEST(16 == lb->lb_n_buckets,
Neale Ranns2303cb12018-02-21 04:57:17 -08003383 "200.200.200.200/32 was inplace modified for 3rd path to 16 buckets");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003384
3385 lbmi = lb->lb_map;
3386 load_balance_map_lock(lbmi);
3387 lbm = load_balance_map_get(lbmi);
3388
3389 for (ii = 0; ii < 16; ii++)
3390 {
3391 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3392 "LB Map for 200.200.200.200/32 at %d is %d",
3393 ii, lbm->lbm_buckets[ii]);
3394 }
3395
3396 /*
3397 * trigger PIC by removing the first via-entry
3398 * the first 6 buckets of the map should map to the next 6
3399 */
3400 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003401 &pfx_1_1_1_1_s_32,
3402 FIB_SOURCE_API,
3403 DPO_PROTO_IP4,
3404 &nh_10_10_10_1,
3405 tm->hw[0]->sw_if_index,
3406 ~0,
3407 1,
3408 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003409 /* suspend so the update walk kicks int */
3410 vlib_process_suspend(vlib_get_main(), 1e-5);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003411
3412 fei = fib_table_lookup_exact_match(fib_index, &bgp_200_pfx);
3413 dpo = fib_entry_contribute_ip_forwarding(fei);
3414 FIB_TEST(lb == load_balance_get(dpo->dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003415 "200.200.200.200/32 was inplace modified for 3rd path");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003416 FIB_TEST(2 == lb->lb_n_buckets,
Neale Ranns2303cb12018-02-21 04:57:17 -08003417 "200.200.200.200/32 was inplace modified for 3rd path remove to 2 buckets");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003418
3419 for (ii = 0; ii < 6; ii++)
3420 {
3421 FIB_TEST(lbm->lbm_buckets[ii] == ii+6,
3422 "LB Map for 200.200.200.200/32 at %d is %d",
3423 ii, lbm->lbm_buckets[ii]);
3424 }
3425 for (ii = 6; ii < 16; ii++)
3426 {
3427 FIB_TEST(lbm->lbm_buckets[ii] == ii,
3428 "LB Map for 200.200.200.200/32 at %d is %d",
3429 ii, lbm->lbm_buckets[ii]);
3430 }
Neale Ranns994dab42017-04-18 12:56:45 -07003431 load_balance_map_unlock(lbmi);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003432
3433 /*
3434 * tidy up
3435 */
3436 fib_table_entry_path_add(fib_index,
3437 &pfx_1_1_1_1_s_32,
3438 FIB_SOURCE_API,
3439 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08003440 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003441 &nh_10_10_10_1,
3442 tm->hw[0]->sw_if_index,
3443 ~0,
3444 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003445 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003446 FIB_ROUTE_PATH_FLAG_NONE);
3447
Neale Rannsf12a83f2017-04-18 09:09:40 -07003448 for (ii = 0; ii < N_P; ii++)
3449 {
3450 fib_table_entry_delete(fib_index,
3451 &bgp_78s[ii],
3452 FIB_SOURCE_API);
3453 FIB_TEST((FIB_NODE_INDEX_INVALID ==
3454 fib_table_lookup_exact_match(fib_index, &bgp_78s[ii])),
3455 "%U removed",
3456 format_fib_prefix, &bgp_78s[ii]);
3457 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003458 fib_table_entry_path_remove(fib_index,
3459 &bgp_200_pfx,
3460 FIB_SOURCE_API,
Neale Ranns2303cb12018-02-21 04:57:17 -08003461 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003462 &pfx_1_1_1_2_s_32.fp_addr,
3463 ~0,
3464 fib_index,
3465 1,
3466 MPLS_LABEL_INVALID);
3467 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003468 &bgp_200_pfx,
3469 FIB_SOURCE_API,
3470 DPO_PROTO_IP4,
3471 &nh_1_1_1_1,
3472 ~0,
3473 fib_index,
3474 1,
3475 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003476 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003477 &bgp_200_pfx,
3478 FIB_SOURCE_API,
3479 DPO_PROTO_IP4,
3480 &pfx_1_1_1_3_s_32.fp_addr,
3481 ~0,
3482 fib_index,
3483 1,
3484 FIB_ROUTE_PATH_RESOLVE_VIA_HOST);
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_3_s_32,
3487 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003488 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003489 &pfx_1_1_1_0_s_28,
3490 FIB_SOURCE_API);
Neale Rannsf12a83f2017-04-18 09:09:40 -07003491 /* suspend so the update walk kicks int */
3492 vlib_process_suspend(vlib_get_main(), 1e-5);
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_0_s_28)),
3495 "1.1.1.1/28 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, &pfx_1_1_1_3_s_32)),
3498 "1.1.1.3/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003499 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003500 fib_table_lookup_exact_match(fib_index, &bgp_200_pfx)),
3501 "200.200.200.200/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003502
3503 /*
3504 * add-remove test. no change.
3505 */
3506 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003507 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003508 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003509 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003510 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003511 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003512
3513 /*
3514 * A route whose paths are built up iteratively and then removed
3515 * all at once
3516 */
3517 fib_prefix_t pfx_4_4_4_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003518 .fp_len = 32,
3519 .fp_proto = FIB_PROTOCOL_IP4,
3520 .fp_addr = {
3521 /* 4.4.4.4/32 */
3522 .ip4.as_u32 = clib_host_to_net_u32(0x04040404),
3523 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003524 };
3525
3526 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003527 &pfx_4_4_4_4_s_32,
3528 FIB_SOURCE_API,
3529 FIB_ENTRY_FLAG_NONE,
3530 DPO_PROTO_IP4,
3531 &nh_10_10_10_1,
3532 tm->hw[0]->sw_if_index,
3533 ~0,
3534 1,
3535 NULL,
3536 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003537 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003538 &pfx_4_4_4_4_s_32,
3539 FIB_SOURCE_API,
3540 FIB_ENTRY_FLAG_NONE,
3541 DPO_PROTO_IP4,
3542 &nh_10_10_10_2,
3543 tm->hw[0]->sw_if_index,
3544 ~0,
3545 1,
3546 NULL,
3547 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003548 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003549 &pfx_4_4_4_4_s_32,
3550 FIB_SOURCE_API,
3551 FIB_ENTRY_FLAG_NONE,
3552 DPO_PROTO_IP4,
3553 &nh_10_10_10_3,
3554 tm->hw[0]->sw_if_index,
3555 ~0,
3556 1,
3557 NULL,
3558 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003559 FIB_TEST(FIB_NODE_INDEX_INVALID !=
Neale Ranns2303cb12018-02-21 04:57:17 -08003560 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3561 "4.4.4.4/32 present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003562
3563 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003564 &pfx_4_4_4_4_s_32,
3565 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003566 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003567 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3568 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003569
3570 /*
3571 * add-remove test. no change.
3572 */
3573 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003574 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003575 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003576 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003577 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003578 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003579
3580 /*
3581 * A route with multiple paths at once
3582 */
3583 fib_route_path_t *r_paths = NULL;
3584
3585 for (ii = 0; ii < 4; ii++)
3586 {
Neale Ranns2303cb12018-02-21 04:57:17 -08003587 fib_route_path_t r_path = {
3588 .frp_proto = DPO_PROTO_IP4,
3589 .frp_addr = {
3590 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
3591 },
3592 .frp_sw_if_index = tm->hw[0]->sw_if_index,
3593 .frp_weight = 1,
3594 .frp_fib_index = ~0,
3595 };
3596 vec_add1(r_paths, r_path);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003597 }
3598
3599 fib_table_entry_update(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003600 &pfx_4_4_4_4_s_32,
3601 FIB_SOURCE_API,
3602 FIB_ENTRY_FLAG_NONE,
3603 r_paths);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003604
3605 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3606 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3607 dpo = fib_entry_contribute_ip_forwarding(fei);
3608
3609 lb = load_balance_get(dpo->dpoi_index);
3610 FIB_TEST((lb->lb_n_buckets == 4), "4.4.4.4/32 lb over %d paths", lb->lb_n_buckets);
3611
3612 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003613 &pfx_4_4_4_4_s_32,
3614 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003615 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003616 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3617 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003618 vec_free(r_paths);
3619
3620 /*
3621 * add-remove test. no change.
3622 */
3623 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003624 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003625 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003626 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003627 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003628 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003629
3630 /*
3631 * A route deag route
3632 */
3633 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003634 &pfx_4_4_4_4_s_32,
3635 FIB_SOURCE_API,
3636 FIB_ENTRY_FLAG_NONE,
3637 DPO_PROTO_IP4,
3638 &zero_addr,
3639 ~0,
3640 fib_index,
3641 1,
3642 NULL,
3643 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003644
3645 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3646 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3647
3648 dpo = fib_entry_contribute_ip_forwarding(fei);
3649 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3650 lookup_dpo_t *lkd = lookup_dpo_get(dpo->dpoi_index);
3651
3652 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003653 "4.4.4.4/32 is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003654 lkd->lkd_fib_index,
3655 format_dpo_id, dpo, 0);
Neale Ranns054c03a2017-10-13 05:15:07 -07003656 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
Neale Ranns2303cb12018-02-21 04:57:17 -08003657 "4.4.4.4/32 is source deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003658 lkd->lkd_input,
3659 format_dpo_id, dpo, 0);
3660
3661 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003662 &pfx_4_4_4_4_s_32,
3663 FIB_SOURCE_API);
Neale Ranns054c03a2017-10-13 05:15:07 -07003664 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003665 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3666 "4.4.4.4/32 removed");
Neale Ranns054c03a2017-10-13 05:15:07 -07003667 vec_free(r_paths);
3668
3669 /*
3670 * A route deag route in a source lookup table
3671 */
3672 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003673 &pfx_4_4_4_4_s_32,
3674 FIB_SOURCE_API,
3675 FIB_ENTRY_FLAG_NONE,
3676 DPO_PROTO_IP4,
3677 &zero_addr,
3678 ~0,
3679 fib_index,
3680 1,
3681 NULL,
3682 FIB_ROUTE_PATH_SOURCE_LOOKUP);
Neale Ranns054c03a2017-10-13 05:15:07 -07003683
3684 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32);
3685 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.4.4.4/32 present");
3686
3687 dpo = fib_entry_contribute_ip_forwarding(fei);
3688 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
3689 lkd = lookup_dpo_get(dpo->dpoi_index);
3690
3691 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08003692 "4.4.4.4/32 is deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003693 lkd->lkd_fib_index,
3694 format_dpo_id, dpo, 0);
3695 FIB_TEST((LOOKUP_INPUT_SRC_ADDR == lkd->lkd_input),
Neale Ranns2303cb12018-02-21 04:57:17 -08003696 "4.4.4.4/32 is source deag in %d %U",
Neale Ranns054c03a2017-10-13 05:15:07 -07003697 lkd->lkd_input,
3698 format_dpo_id, dpo, 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003699
3700 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003701 &pfx_4_4_4_4_s_32,
3702 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003703 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003704 fib_table_lookup_exact_match(fib_index, &pfx_4_4_4_4_s_32),
3705 "4.4.4.4/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003706 vec_free(r_paths);
3707
3708 /*
3709 * add-remove test. no change.
3710 */
3711 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003712 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003713 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003714 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003715 FIB_TEST((ENBR+7 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003716 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003717
3718 /*
Neale Rannsbcc889c2016-11-03 14:15:28 -07003719 * Duplicate paths:
3720 * add a recursive with duplicate paths. Expect the duplicate to be ignored.
3721 */
3722 fib_prefix_t pfx_34_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003723 .fp_len = 32,
3724 .fp_proto = FIB_PROTOCOL_IP4,
3725 .fp_addr = {
3726 .ip4.as_u32 = clib_host_to_net_u32(0x22010101),
3727 },
Neale Rannsbcc889c2016-11-03 14:15:28 -07003728 };
3729 fib_prefix_t pfx_34_34_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003730 .fp_len = 32,
3731 .fp_proto = FIB_PROTOCOL_IP4,
3732 .fp_addr = {
3733 .ip4.as_u32 = clib_host_to_net_u32(0x22220101),
3734 },
Neale Rannsbcc889c2016-11-03 14:15:28 -07003735 };
3736 fei = fib_table_entry_path_add(fib_index,
Neale Ranns57b58602017-07-15 07:37:25 -07003737 &pfx_34_34_1_1_s_32,
3738 FIB_SOURCE_API,
3739 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003740 DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07003741 &nh_10_10_10_1,
3742 tm->hw[0]->sw_if_index,
3743 0,
3744 1,
3745 NULL,
3746 FIB_ROUTE_PATH_FLAG_NONE);
3747 fei = fib_table_entry_path_add(fib_index,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003748 &pfx_34_1_1_1_s_32,
3749 FIB_SOURCE_API,
3750 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003751 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003752 &pfx_34_34_1_1_s_32.fp_addr,
3753 ~0,
3754 fib_index,
3755 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003756 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003757 FIB_ROUTE_PATH_FLAG_NONE);
3758 fei = fib_table_entry_path_add(fib_index,
3759 &pfx_34_1_1_1_s_32,
3760 FIB_SOURCE_API,
3761 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07003762 DPO_PROTO_IP4,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003763 &pfx_34_34_1_1_s_32.fp_addr,
3764 ~0,
3765 fib_index,
3766 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00003767 NULL,
Neale Rannsbcc889c2016-11-03 14:15:28 -07003768 FIB_ROUTE_PATH_FLAG_NONE);
3769 FIB_TEST_REC_FORW(&pfx_34_1_1_1_s_32, &pfx_34_34_1_1_s_32, 0);
3770 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
Neale Ranns57b58602017-07-15 07:37:25 -07003771 fib_table_entry_delete(fib_index,
3772 &pfx_34_34_1_1_s_32,
3773 FIB_SOURCE_API);
Neale Rannsbcc889c2016-11-03 14:15:28 -07003774
3775 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003776 * CLEANUP
3777 * remove: 1.1.1.2/32, 1.1.2.0/24 and 1.1.1.1/32
3778 * all of which are via 10.10.10.1, Itf1
3779 */
3780 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003781 &pfx_1_1_1_2_s_32,
3782 FIB_SOURCE_API,
3783 DPO_PROTO_IP4,
3784 &nh_10_10_10_1,
3785 tm->hw[0]->sw_if_index,
3786 ~0,
3787 1,
3788 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003789 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003790 &pfx_1_1_1_1_s_32,
3791 FIB_SOURCE_API,
3792 DPO_PROTO_IP4,
3793 &nh_10_10_10_1,
3794 tm->hw[0]->sw_if_index,
3795 ~0,
3796 1,
3797 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003798 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003799 &pfx_1_1_2_0_s_24,
3800 FIB_SOURCE_API,
3801 DPO_PROTO_IP4,
3802 &nh_10_10_10_1,
3803 tm->hw[0]->sw_if_index,
3804 ~0,
3805 1,
3806 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003807
3808 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_1_s_32),
3810 "1.1.1.1/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_1_2_s_32),
3813 "1.1.1.2/32 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003814 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08003815 fib_table_lookup_exact_match(fib_index, &pfx_1_1_2_0_s_24),
3816 "1.1.2.0/24 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003817
3818 /*
3819 * -3 entries and -1 shared path-list
3820 */
3821 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003822 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003823 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003824 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003825 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003826 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003827
3828 /*
3829 * An attached-host route. Expect to link to the incomplete adj
3830 */
3831 fib_prefix_t pfx_4_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003832 .fp_len = 32,
3833 .fp_proto = FIB_PROTOCOL_IP4,
3834 .fp_addr = {
3835 /* 4.1.1.1/32 */
3836 .ip4.as_u32 = clib_host_to_net_u32(0x04010101),
3837 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003838 };
3839 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003840 &pfx_4_1_1_1_s_32,
3841 FIB_SOURCE_API,
3842 FIB_ENTRY_FLAG_NONE,
3843 DPO_PROTO_IP4,
3844 &zero_addr,
3845 tm->hw[0]->sw_if_index,
3846 fib_index,
3847 1,
3848 NULL,
3849 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003850
3851 fei = fib_table_lookup_exact_match(fib_index, &pfx_4_1_1_1_s_32);
3852 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "4.1.1.1/32 present");
3853 ai = fib_entry_get_adj(fei);
3854
3855 ai2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08003856 VNET_LINK_IP4,
3857 &pfx_4_1_1_1_s_32.fp_addr,
3858 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003859 FIB_TEST((ai == ai2), "Attached-host link to incomplete ADJ");
3860 adj_unlock(ai2);
3861
3862 /*
3863 * +1 entry and +1 shared path-list
3864 */
3865 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003866 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003867 FIB_TEST((PNBR+5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003868 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003869 FIB_TEST((ENBR+5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003870 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003871
3872 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003873 &pfx_4_1_1_1_s_32,
3874 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003875
3876 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003877 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003878 FIB_TEST((PNBR+4 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003879 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00003880 FIB_TEST((ENBR+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08003881 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003882
3883 /*
3884 * add a v6 prefix via v4 next-hops
3885 */
3886 fib_prefix_t pfx_2001_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003887 .fp_len = 64,
3888 .fp_proto = FIB_PROTOCOL_IP6,
3889 .fp_addr = {
3890 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
3891 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003892 };
3893 fei = fib_table_entry_path_add(0, //default v6 table
Neale Ranns2303cb12018-02-21 04:57:17 -08003894 &pfx_2001_s_64,
3895 FIB_SOURCE_API,
3896 FIB_ENTRY_FLAG_NONE,
3897 DPO_PROTO_IP4,
3898 &nh_10_10_10_1,
3899 tm->hw[0]->sw_if_index,
3900 fib_index,
3901 1,
3902 NULL,
3903 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003904
3905 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
3906 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "2001::/64 present");
3907 ai = fib_entry_get_adj(fei);
3908 adj = adj_get(ai);
3909 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
Neale Ranns2303cb12018-02-21 04:57:17 -08003910 "2001::/64 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01003911 FIB_TEST((adj->ia_link == VNET_LINK_IP6),
Neale Ranns2303cb12018-02-21 04:57:17 -08003912 "2001::/64 is link type v6");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003913 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP4),
Neale Ranns2303cb12018-02-21 04:57:17 -08003914 "2001::/64 ADJ-adj is NH proto v4");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003915 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
3916
Neale Ranns3ee44042016-10-03 13:05:48 +01003917 /*
3918 * add a uRPF exempt prefix:
3919 * test:
3920 * - it's forwarding is drop
3921 * - it's uRPF list is not empty
3922 * - the uRPF list for the default route (it's cover) is empty
3923 */
3924 fei = fib_table_entry_special_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003925 &pfx_4_1_1_1_s_32,
3926 FIB_SOURCE_URPF_EXEMPT,
3927 FIB_ENTRY_FLAG_DROP);
Neale Ranns3ee44042016-10-03 13:05:48 +01003928 dpo = fib_entry_contribute_ip_forwarding(fei);
3929 FIB_TEST(load_balance_is_drop(dpo),
Neale Ranns2303cb12018-02-21 04:57:17 -08003930 "uRPF exempt 4.1.1.1/32 DROP");
3931 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 1, 0),
3932 "uRPF list for exempt prefix has itf index 0");
Neale Ranns3ee44042016-10-03 13:05:48 +01003933 fei = fib_table_lookup_exact_match(fib_index, &pfx_0_0_0_0_s_0);
Neale Ranns2303cb12018-02-21 04:57:17 -08003934 FIB_TEST(!fib_test_urpf_is_equal(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, 0),
3935 "uRPF list for 0.0.0.0/0 empty");
Neale Ranns3ee44042016-10-03 13:05:48 +01003936
3937 fib_table_entry_delete(fib_index, &pfx_4_1_1_1_s_32, FIB_SOURCE_URPF_EXEMPT);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01003938
3939 /*
Neale Ranns3983ac22017-03-10 11:53:27 -08003940 * An adj-fib that fails the refinement criteria - no connected cover
3941 */
3942 fib_prefix_t pfx_12_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003943 .fp_len = 32,
3944 .fp_proto = FIB_PROTOCOL_IP4,
3945 .fp_addr = {
3946 /* 12.10.10.2 */
3947 .ip4.as_u32 = clib_host_to_net_u32(0x0c0a0a02),
3948 },
Neale Ranns3983ac22017-03-10 11:53:27 -08003949 };
3950
Neale Ranns81424992017-05-18 03:03:22 -07003951 fib_table_entry_path_add(fib_index,
3952 &pfx_12_10_10_2_s_32,
3953 FIB_SOURCE_ADJ,
3954 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003955 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003956 &pfx_12_10_10_2_s_32.fp_addr,
3957 tm->hw[0]->sw_if_index,
3958 ~0, // invalid fib index
3959 1,
3960 NULL,
3961 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003962
3963 fei = fib_table_lookup_exact_match(fib_index, &pfx_12_10_10_2_s_32);
3964 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08003965 FIB_TEST(dpo_is_drop(dpo),
3966 "no connected cover adj-fib fails refinement: %U",
3967 format_dpo_id, dpo, 0);
Neale Ranns3983ac22017-03-10 11:53:27 -08003968
3969 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08003970 &pfx_12_10_10_2_s_32,
3971 FIB_SOURCE_ADJ);
Neale Ranns3983ac22017-03-10 11:53:27 -08003972
3973 /*
3974 * An adj-fib that fails the refinement criteria - cover is connected
3975 * but on a different interface
3976 */
3977 fib_prefix_t pfx_10_10_10_127_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08003978 .fp_len = 32,
3979 .fp_proto = FIB_PROTOCOL_IP4,
3980 .fp_addr = {
3981 /* 10.10.10.127 */
3982 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a7f),
3983 },
Neale Ranns3983ac22017-03-10 11:53:27 -08003984 };
3985
Neale Ranns81424992017-05-18 03:03:22 -07003986 fib_table_entry_path_add(fib_index,
3987 &pfx_10_10_10_127_s_32,
3988 FIB_SOURCE_ADJ,
3989 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07003990 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07003991 &pfx_10_10_10_127_s_32.fp_addr,
3992 tm->hw[1]->sw_if_index,
3993 ~0, // invalid fib index
3994 1,
3995 NULL,
3996 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns3983ac22017-03-10 11:53:27 -08003997
3998 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_127_s_32);
3999 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08004000 FIB_TEST(dpo_is_drop(dpo),
4001 "wrong interface adj-fib fails refinement");
Neale Ranns3983ac22017-03-10 11:53:27 -08004002
4003 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004004 &pfx_10_10_10_127_s_32,
4005 FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07004006
4007 /*
4008 * add a second path to an adj-fib
4009 * this is a sumiluation of another ARP entry created
Neale Ranns2303cb12018-02-21 04:57:17 -08004010 * on an interface on which the connected prefix does not exist.
Neale Ranns81424992017-05-18 03:03:22 -07004011 * The second path fails refinement. Expect to forward through the
4012 * first.
4013 */
4014 fib_prefix_t pfx_10_10_10_3_s_32 = {
4015 .fp_len = 32,
4016 .fp_proto = FIB_PROTOCOL_IP4,
4017 .fp_addr = {
4018 /* 10.10.10.3 */
4019 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
4020 },
4021 };
4022
4023 ai_03 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
4024 VNET_LINK_IP4,
4025 &nh_10_10_10_3,
4026 tm->hw[0]->sw_if_index);
4027
4028 fib_test_lb_bucket_t ip_o_10_10_10_3 = {
4029 .type = FT_LB_ADJ,
4030 .adj = {
4031 .adj = ai_03,
4032 },
4033 };
4034 fei = fib_table_entry_path_add(fib_index,
4035 &pfx_10_10_10_3_s_32,
4036 FIB_SOURCE_ADJ,
4037 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004038 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004039 &nh_10_10_10_3,
4040 tm->hw[0]->sw_if_index,
4041 fib_index,
4042 1,
4043 NULL,
4044 FIB_ROUTE_PATH_FLAG_NONE);
4045 fei = fib_table_entry_path_add(fib_index,
4046 &pfx_10_10_10_3_s_32,
4047 FIB_SOURCE_ADJ,
4048 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004049 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004050 &nh_12_12_12_12,
4051 tm->hw[1]->sw_if_index,
4052 fib_index,
4053 1,
4054 NULL,
4055 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004056 FIB_TEST(!fib_test_validate_entry(fei,
4057 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4058 1,
4059 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004060 "10.10.10.3 via 10.10.10.3/Eth0 only");
4061
4062 /*
4063 * remove the path that refines the cover, should go unresolved
4064 */
4065 fib_table_entry_path_remove(fib_index,
4066 &pfx_10_10_10_3_s_32,
4067 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004068 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004069 &nh_10_10_10_3,
4070 tm->hw[0]->sw_if_index,
4071 fib_index,
4072 1,
4073 FIB_ROUTE_PATH_FLAG_NONE);
4074 dpo = fib_entry_contribute_ip_forwarding(fei);
Neale Ranns2303cb12018-02-21 04:57:17 -08004075 FIB_TEST(dpo_is_drop(dpo),
Neale Ranns81424992017-05-18 03:03:22 -07004076 "wrong interface adj-fib fails refinement");
4077
4078 /*
4079 * add back the path that refines the cover
4080 */
4081 fei = fib_table_entry_path_add(fib_index,
4082 &pfx_10_10_10_3_s_32,
4083 FIB_SOURCE_ADJ,
4084 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07004085 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004086 &nh_10_10_10_3,
4087 tm->hw[0]->sw_if_index,
4088 fib_index,
4089 1,
4090 NULL,
4091 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004092 FIB_TEST(!fib_test_validate_entry(fei,
4093 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4094 1,
4095 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004096 "10.10.10.3 via 10.10.10.3/Eth0 only");
4097
4098 /*
4099 * remove the path that does not refine the cover
4100 */
4101 fib_table_entry_path_remove(fib_index,
4102 &pfx_10_10_10_3_s_32,
4103 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004104 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004105 &nh_12_12_12_12,
4106 tm->hw[1]->sw_if_index,
4107 fib_index,
4108 1,
4109 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08004110 FIB_TEST(!fib_test_validate_entry(fei,
4111 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4112 1,
4113 &ip_o_10_10_10_3),
Neale Ranns81424992017-05-18 03:03:22 -07004114 "10.10.10.3 via 10.10.10.3/Eth0 only");
4115
4116 /*
4117 * remove the path that does refine, it's the last path, so
4118 * the entry should be gone
4119 */
4120 fib_table_entry_path_remove(fib_index,
4121 &pfx_10_10_10_3_s_32,
4122 FIB_SOURCE_ADJ,
Neale Rannsda78f952017-05-24 09:15:43 -07004123 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07004124 &nh_10_10_10_3,
4125 tm->hw[0]->sw_if_index,
4126 fib_index,
4127 1,
4128 FIB_ROUTE_PATH_FLAG_NONE);
4129 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
4130 FIB_TEST((fei == FIB_NODE_INDEX_INVALID), "10.10.10.3 gone");
4131
4132 adj_unlock(ai_03);
4133
Neale Ranns227038a2017-04-21 01:07:59 -07004134 /*
4135 * change the table's flow-hash config - expect the update to propagete to
4136 * the entries' load-balance objects
4137 */
4138 flow_hash_config_t old_hash_config, new_hash_config;
4139
4140 old_hash_config = fib_table_get_flow_hash_config(fib_index,
4141 FIB_PROTOCOL_IP4);
4142 new_hash_config = (IP_FLOW_HASH_SRC_ADDR |
4143 IP_FLOW_HASH_DST_ADDR);
4144
4145 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
4146 dpo = fib_entry_contribute_ip_forwarding(fei);
4147 lb = load_balance_get(dpo->dpoi_index);
4148 FIB_TEST((lb->lb_hash_config == old_hash_config),
4149 "Table and LB hash config match: %U",
4150 format_ip_flow_hash_config, lb->lb_hash_config);
4151
4152 fib_table_set_flow_hash_config(fib_index, FIB_PROTOCOL_IP4, new_hash_config);
4153
4154 FIB_TEST((lb->lb_hash_config == new_hash_config),
4155 "Table and LB newhash config match: %U",
4156 format_ip_flow_hash_config, lb->lb_hash_config);
Neale Ranns3983ac22017-03-10 11:53:27 -08004157
4158 /*
Neale Rannsf068c3e2018-01-03 04:18:48 -08004159 * A route via DVR DPO
Neale Ranns6f631152017-10-03 08:20:21 -07004160 */
4161 fei = fib_table_entry_path_add(fib_index,
4162 &pfx_10_10_10_3_s_32,
4163 FIB_SOURCE_API,
4164 FIB_ENTRY_FLAG_NONE,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004165 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004166 &zero_addr,
4167 tm->hw[0]->sw_if_index,
4168 ~0,
4169 1,
4170 NULL,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004171 FIB_ROUTE_PATH_DVR);
4172 dpo_id_t dvr_dpo = DPO_INVALID;
4173 dvr_dpo_add_or_lock(tm->hw[0]->sw_if_index, DPO_PROTO_IP4, &dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004174 fib_test_lb_bucket_t ip_o_l2 = {
4175 .type = FT_LB_L2,
4176 .adj = {
Neale Rannsf068c3e2018-01-03 04:18:48 -08004177 .adj = dvr_dpo.dpoi_index,
Neale Ranns6f631152017-10-03 08:20:21 -07004178 },
4179 };
4180
Neale Ranns2303cb12018-02-21 04:57:17 -08004181 FIB_TEST(!fib_test_validate_entry(fei,
4182 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
4183 1,
4184 &ip_o_l2),
Neale Ranns6f631152017-10-03 08:20:21 -07004185 "10.10.10.3 via L2 on Eth0");
4186 fib_table_entry_path_remove(fib_index,
4187 &pfx_10_10_10_3_s_32,
4188 FIB_SOURCE_API,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004189 DPO_PROTO_IP4,
Neale Ranns6f631152017-10-03 08:20:21 -07004190 &zero_addr,
4191 tm->hw[0]->sw_if_index,
4192 fib_index,
4193 1,
Neale Rannsf068c3e2018-01-03 04:18:48 -08004194 FIB_ROUTE_PATH_DVR);
4195 dpo_reset(&dvr_dpo);
Neale Ranns6f631152017-10-03 08:20:21 -07004196
4197 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004198 * CLEANUP
Neale Ranns2303cb12018-02-21 04:57:17 -08004199 * remove adj-fibs:
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004200 */
4201 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004202 &pfx_10_10_10_1_s_32,
4203 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004204 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004205 &pfx_10_10_10_2_s_32,
4206 FIB_SOURCE_ADJ);
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_1_s_32),
4209 "10.10.10.1/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004210 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004211 fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32),
4212 "10.10.10.2/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004213
4214 /*
4215 * -2 entries and -2 non-shared path-list
4216 */
4217 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004218 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004219 FIB_TEST((PNBR+2 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004220 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004221 FIB_TEST((ENBR+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004222 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004223
4224 /*
Neale Ranns3ee44042016-10-03 13:05:48 +01004225 * unlock the adjacencies for which this test provided a rewrite.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004226 * These are the last locks on these adjs. they should thus go away.
4227 */
4228 adj_unlock(ai_02);
4229 adj_unlock(ai_01);
Neale Ranns3ee44042016-10-03 13:05:48 +01004230 adj_unlock(ai_12_12_12_12);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004231
4232 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004233 adj_nbr_db_size());
Neale Ranns3dffb1e2016-11-01 20:38:53 +00004234
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004235 /*
4236 * CLEANUP
4237 * remove the interface prefixes
4238 */
4239 local_pfx.fp_len = 32;
4240 fib_table_entry_special_remove(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004241 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004242 fei = fib_table_lookup(fib_index, &local_pfx);
4243
4244 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004245 fib_table_lookup_exact_match(fib_index, &local_pfx),
4246 "10.10.10.10/32 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004247
4248 local_pfx.fp_len = 24;
4249 fib_table_entry_delete(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004250 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004251
4252 FIB_TEST(FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08004253 fib_table_lookup_exact_match(fib_index, &local_pfx),
4254 "10.10.10.10/24 adj-fib removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004255
4256 /*
4257 * -2 entries and -2 non-shared path-list
4258 */
Neale Rannsf12a83f2017-04-18 09:09:40 -07004259 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004260 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004261 FIB_TEST((PNBR == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004262 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004263 FIB_TEST((ENBR == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004264 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004265
4266 /*
4267 * Last but not least, remove the VRF
4268 */
4269 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4270 FIB_PROTOCOL_IP4,
4271 FIB_SOURCE_API)),
4272 "NO API Source'd prefixes");
4273 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4274 FIB_PROTOCOL_IP4,
4275 FIB_SOURCE_RR)),
4276 "NO RR Source'd prefixes");
4277 FIB_TEST((0 == fib_table_get_num_entries(fib_index,
4278 FIB_PROTOCOL_IP4,
4279 FIB_SOURCE_INTERFACE)),
4280 "NO INterface Source'd prefixes");
4281
Neale Ranns15002542017-09-10 04:39:11 -07004282 fib_table_unlock(fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004283
4284 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004285 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004286 FIB_TEST((PNBR-5 == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004287 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004288 FIB_TEST((ENBR-5 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004289 fib_entry_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004290 FIB_TEST((ENBR-5 == pool_elts(fib_urpf_list_pool)), "uRPF pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004291 pool_elts(fib_urpf_list_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004292 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004293 pool_elts(load_balance_map_pool));
Neale Ranns994dab42017-04-18 12:56:45 -07004294 FIB_TEST((lb_count == pool_elts(load_balance_pool)), "LB pool size is %d",
4295 pool_elts(load_balance_pool));
Neale Rannsf068c3e2018-01-03 04:18:48 -08004296 FIB_TEST((0 == pool_elts(dvr_dpo_pool)), "L2 DPO pool size is %d",
4297 pool_elts(dvr_dpo_pool));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004298
Neale Ranns2303cb12018-02-21 04:57:17 -08004299 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004300}
4301
Neale Ranns0ebe8d72016-12-08 19:48:11 +00004302static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004303fib_test_v6 (void)
4304{
4305 /*
4306 * In the default table check for the presence and correct forwarding
4307 * of the special entries
4308 */
4309 fib_node_index_t dfrt, fei, ai, locked_ai, ai_01, ai_02;
4310 const dpo_id_t *dpo, *dpo_drop;
4311 const ip_adjacency_t *adj;
4312 const receive_dpo_t *rd;
4313 test_main_t *tm;
4314 u32 fib_index;
Neale Ranns2303cb12018-02-21 04:57:17 -08004315 int ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004316
Neale Ranns2303cb12018-02-21 04:57:17 -08004317 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004318 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004319 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004320
4321 /* via 2001:0:0:1::2 */
4322 ip46_address_t nh_2001_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004323 .ip6 = {
4324 .as_u64 = {
4325 [0] = clib_host_to_net_u64(0x2001000000000001),
4326 [1] = clib_host_to_net_u64(0x0000000000000002),
4327 },
4328 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004329 };
4330
4331 tm = &test_main;
4332
4333 dpo_drop = drop_dpo_get(DPO_PROTO_IP6);
4334
4335 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -07004336 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP6, 11,
4337 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004338
4339 for (ii = 0; ii < 4; ii++)
4340 {
Neale Ranns2303cb12018-02-21 04:57:17 -08004341 ip6_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004342 }
4343
4344 fib_prefix_t pfx_0_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004345 .fp_len = 0,
4346 .fp_proto = FIB_PROTOCOL_IP6,
4347 .fp_addr = {
4348 .ip6 = {
4349 {0, 0},
4350 },
4351 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004352 };
4353
4354 dfrt = fib_table_lookup(fib_index, &pfx_0_0);
4355 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
4356 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004357 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004358
4359 dpo = fib_entry_contribute_ip_forwarding(dfrt);
4360 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004361 &ip6_main,
4362 1,
4363 &pfx_0_0.fp_addr.ip6)),
4364 "default-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004365
4366 // FIXME - check specials.
4367
4368 /*
4369 * At this stage there is one v4 FIB with 5 routes and two v6 FIBs
Neale Ranns32e1c012016-11-22 17:07:28 +00004370 * each with 2 entries and a v6 mfib with 4 path-lists.
4371 * All entries are special so no path-list sharing.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004372 */
Neale Ranns32e1c012016-11-22 17:07:28 +00004373#define ENPS (5+4)
Jakub Grajciar7b867a82017-12-08 16:28:42 +01004374 u32 PNPS = (5+4+4);
4375 /*
4376 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
4377 */
4378 if (vlib_get_plugin_symbol("igmp_plugin.so", "igmp_listen"))
4379 PNPS += 2;
4380
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004381 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004382 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004383 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004384 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004385 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004386
4387 /*
4388 * add interface routes.
4389 * validate presence of /64 attached and /128 recieve.
4390 * test for the presence of the receive address in the glean and local adj
4391 *
4392 * receive on 2001:0:0:1::1/128
4393 */
4394 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004395 .fp_len = 64,
4396 .fp_proto = FIB_PROTOCOL_IP6,
4397 .fp_addr = {
4398 .ip6 = {
4399 .as_u64 = {
4400 [0] = clib_host_to_net_u64(0x2001000000000001),
4401 [1] = clib_host_to_net_u64(0x0000000000000001),
4402 },
4403 },
4404 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004405 };
4406
4407 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004408 FIB_SOURCE_INTERFACE,
4409 (FIB_ENTRY_FLAG_CONNECTED |
4410 FIB_ENTRY_FLAG_ATTACHED),
4411 DPO_PROTO_IP6,
4412 NULL,
4413 tm->hw[0]->sw_if_index,
4414 ~0,
4415 1,
4416 NULL,
4417 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004418 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4419
4420 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4421
4422 ai = fib_entry_get_adj(fei);
4423 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4424 adj = adj_get(ai);
4425 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004426 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004427 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004428 &adj->sub_type.glean.receive_addr)),
4429 "attached interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004430 dpo = fib_entry_contribute_ip_forwarding(fei);
4431 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004432 &ip6_main,
4433 1,
4434 &local_pfx.fp_addr.ip6)),
4435 "attached-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004436
4437 local_pfx.fp_len = 128;
4438 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004439 FIB_SOURCE_INTERFACE,
4440 (FIB_ENTRY_FLAG_CONNECTED |
4441 FIB_ENTRY_FLAG_LOCAL),
4442 DPO_PROTO_IP6,
4443 NULL,
4444 tm->hw[0]->sw_if_index,
4445 ~0, // invalid fib index
4446 1,
4447 NULL,
4448 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004449 fei = fib_table_lookup(fib_index, &local_pfx);
4450
4451 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4452
4453 dpo = fib_entry_contribute_ip_forwarding(fei);
4454 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4455 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004456 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004457 rd = receive_dpo_get(dpo->dpoi_index);
4458
4459 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004460 &rd->rd_addr)),
4461 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004462
4463 dpo = fib_entry_contribute_ip_forwarding(fei);
4464 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004465 &ip6_main,
4466 1,
4467 &local_pfx.fp_addr.ip6)),
4468 "local-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004469
4470 /*
4471 * +2 entries. +2 unshared path-lists
4472 */
4473 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004474 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004475 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004476 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004477 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004478
4479 /*
4480 * Modify the default route to be via an adj not yet known.
4481 * this sources the defalut route with the API source, which is
4482 * a higher preference to the DEFAULT_ROUTE source
4483 */
4484 fib_table_entry_path_add(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004485 FIB_SOURCE_API,
4486 FIB_ENTRY_FLAG_NONE,
4487 DPO_PROTO_IP6,
4488 &nh_2001_2,
4489 tm->hw[0]->sw_if_index,
4490 ~0,
4491 1,
4492 NULL,
4493 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004494 fei = fib_table_lookup(fib_index, &pfx_0_0);
4495
4496 FIB_TEST((fei == dfrt), "default route same index");
4497 ai = fib_entry_get_adj(fei);
4498 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4499 adj = adj_get(ai);
4500 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004501 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004502 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004503 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004504
4505 /*
4506 * find the adj in the shared db
4507 */
4508 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004509 VNET_LINK_IP6,
4510 &nh_2001_2,
4511 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004512 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4513 adj_unlock(locked_ai);
4514
4515 /*
4516 * no more entires. +1 shared path-list
4517 */
4518 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004519 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004520 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004521 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004522 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004523 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004524
4525 /*
4526 * remove the API source from the default route. We expected
4527 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4528 */
4529 fib_table_entry_path_remove(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004530 FIB_SOURCE_API,
4531 DPO_PROTO_IP6,
4532 &nh_2001_2,
4533 tm->hw[0]->sw_if_index,
4534 ~0,
4535 1,
4536 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004537 fei = fib_table_lookup(fib_index, &pfx_0_0);
4538
4539 FIB_TEST((fei == dfrt), "default route same index");
4540 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004541 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004542
4543 /*
4544 * no more entires. -1 shared path-list
4545 */
4546 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004547 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004548 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004549 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004550 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004551 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004552
4553 /*
4554 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4555 */
4556 fib_prefix_t pfx_2001_1_2_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004557 .fp_len = 128,
4558 .fp_proto = FIB_PROTOCOL_IP6,
4559 .fp_addr = {
4560 .ip6 = {
4561 .as_u64 = {
4562 [0] = clib_host_to_net_u64(0x2001000000000001),
4563 [1] = clib_host_to_net_u64(0x0000000000000002),
4564 },
4565 },
4566 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004567 };
4568 fib_prefix_t pfx_2001_1_3_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004569 .fp_len = 128,
4570 .fp_proto = FIB_PROTOCOL_IP6,
4571 .fp_addr = {
4572 .ip6 = {
4573 .as_u64 = {
4574 [0] = clib_host_to_net_u64(0x2001000000000001),
4575 [1] = clib_host_to_net_u64(0x0000000000000003),
4576 },
4577 },
4578 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004579 };
4580 u8 eth_addr[] = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004581 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004582 };
4583
4584 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004585 VNET_LINK_IP6,
4586 &pfx_2001_1_2_s_128.fp_addr,
4587 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004588 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4589 adj = adj_get(ai_01);
4590 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004591 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004592 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004593 &adj->sub_type.nbr.next_hop)),
4594 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004595
Neale Rannsb80c5362016-10-08 13:03:40 +01004596 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004597 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004598 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004599 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004600 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004601 &adj->sub_type.nbr.next_hop)),
4602 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004603
Neale Ranns81424992017-05-18 03:03:22 -07004604 fib_table_entry_path_add(fib_index,
4605 &pfx_2001_1_2_s_128,
4606 FIB_SOURCE_ADJ,
4607 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004608 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004609 &pfx_2001_1_2_s_128.fp_addr,
4610 tm->hw[0]->sw_if_index,
4611 ~0,
4612 1,
4613 NULL,
4614 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004615
4616 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4617 ai = fib_entry_get_adj(fei);
4618 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4619
4620 eth_addr[5] = 0xb2;
4621
4622 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004623 VNET_LINK_IP6,
4624 &pfx_2001_1_3_s_128.fp_addr,
4625 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004626 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4627 adj = adj_get(ai_02);
4628 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004629 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004630 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004631 &adj->sub_type.nbr.next_hop)),
4632 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004633
Neale Rannsb80c5362016-10-08 13:03:40 +01004634 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004635 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004636 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004637 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004638 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004639 &adj->sub_type.nbr.next_hop)),
4640 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004641 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4642
Neale Ranns81424992017-05-18 03:03:22 -07004643 fib_table_entry_path_add(fib_index,
4644 &pfx_2001_1_3_s_128,
4645 FIB_SOURCE_ADJ,
4646 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004647 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004648 &pfx_2001_1_3_s_128.fp_addr,
4649 tm->hw[0]->sw_if_index,
4650 ~0,
4651 1,
4652 NULL,
4653 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004654
4655 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4656 ai = fib_entry_get_adj(fei);
4657 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4658
4659 /*
4660 * +2 entries, +2 unshread path-lists.
4661 */
4662 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004663 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004664 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004665 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004666 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004667 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004668
4669 /*
4670 * Add a 2 routes via the first ADJ. ensure path-list sharing
4671 */
4672 fib_prefix_t pfx_2001_a_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004673 .fp_len = 64,
4674 .fp_proto = FIB_PROTOCOL_IP6,
4675 .fp_addr = {
4676 .ip6 = {
4677 .as_u64 = {
4678 [0] = clib_host_to_net_u64(0x200100000000000a),
4679 [1] = clib_host_to_net_u64(0x0000000000000000),
4680 },
4681 },
4682 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004683 };
4684 fib_prefix_t pfx_2001_b_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004685 .fp_len = 64,
4686 .fp_proto = FIB_PROTOCOL_IP6,
4687 .fp_addr = {
4688 .ip6 = {
4689 .as_u64 = {
4690 [0] = clib_host_to_net_u64(0x200100000000000b),
4691 [1] = clib_host_to_net_u64(0x0000000000000000),
4692 },
4693 },
4694 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004695 };
4696
4697 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004698 &pfx_2001_a_s_64,
4699 FIB_SOURCE_API,
4700 FIB_ENTRY_FLAG_NONE,
4701 DPO_PROTO_IP6,
4702 &nh_2001_2,
4703 tm->hw[0]->sw_if_index,
4704 ~0,
4705 1,
4706 NULL,
4707 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004708 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4709 ai = fib_entry_get_adj(fei);
4710 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4711 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004712 &pfx_2001_b_s_64,
4713 FIB_SOURCE_API,
4714 FIB_ENTRY_FLAG_NONE,
4715 DPO_PROTO_IP6,
4716 &nh_2001_2,
4717 tm->hw[0]->sw_if_index,
4718 ~0,
4719 1,
4720 NULL,
4721 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004722 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4723 ai = fib_entry_get_adj(fei);
4724 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4725
4726 /*
4727 * +2 entries, +1 shared path-list.
4728 */
4729 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004730 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004731 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004732 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004733 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004734 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004735
4736 /*
4737 * add a v4 prefix via a v6 next-hop
4738 */
4739 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004740 .fp_len = 32,
4741 .fp_proto = FIB_PROTOCOL_IP4,
4742 .fp_addr = {
4743 .ip4.as_u32 = 0x01010101,
4744 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004745 };
4746 fei = fib_table_entry_path_add(0, // default table
Neale Ranns2303cb12018-02-21 04:57:17 -08004747 &pfx_1_1_1_1_s_32,
4748 FIB_SOURCE_API,
4749 FIB_ENTRY_FLAG_NONE,
4750 DPO_PROTO_IP6,
4751 &nh_2001_2,
4752 tm->hw[0]->sw_if_index,
4753 ~0,
4754 1,
4755 NULL,
4756 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004757 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
Neale Ranns2303cb12018-02-21 04:57:17 -08004758 "1.1.1.1/32 o v6 route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004759 ai = fib_entry_get_adj(fei);
4760 adj = adj_get(ai);
4761 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
Neale Ranns2303cb12018-02-21 04:57:17 -08004762 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004763 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns2303cb12018-02-21 04:57:17 -08004764 "1.1.1.1/32 ADJ-adj is link type v4");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004765 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
Neale Ranns2303cb12018-02-21 04:57:17 -08004766 "1.1.1.1/32 ADJ-adj is NH proto v6");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004767 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4768
4769 /*
4770 * An attached route
4771 */
4772 fib_prefix_t pfx_2001_c_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004773 .fp_len = 64,
4774 .fp_proto = FIB_PROTOCOL_IP6,
4775 .fp_addr = {
4776 .ip6 = {
4777 .as_u64 = {
4778 [0] = clib_host_to_net_u64(0x200100000000000c),
4779 [1] = clib_host_to_net_u64(0x0000000000000000),
4780 },
4781 },
4782 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004783 };
4784 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004785 &pfx_2001_c_s_64,
4786 FIB_SOURCE_CLI,
4787 FIB_ENTRY_FLAG_ATTACHED,
4788 DPO_PROTO_IP6,
4789 NULL,
4790 tm->hw[0]->sw_if_index,
4791 ~0,
4792 1,
4793 NULL,
4794 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004795 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4796 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4797 ai = fib_entry_get_adj(fei);
4798 adj = adj_get(ai);
4799 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
Neale Ranns2303cb12018-02-21 04:57:17 -08004800 "2001:0:0:c/64 attached resolves via glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004801
4802 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004803 &pfx_2001_c_s_64,
4804 FIB_SOURCE_CLI,
4805 DPO_PROTO_IP6,
4806 NULL,
4807 tm->hw[0]->sw_if_index,
4808 ~0,
4809 1,
4810 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004811 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4812 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4813
4814 /*
4815 * Shutdown the interface on which we have a connected and through
4816 * which the routes are reachable.
4817 * This will result in the connected, adj-fibs, and routes linking to drop
4818 * The local/for-us prefix continues to receive.
4819 */
4820 clib_error_t * error;
4821
4822 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004823 tm->hw[0]->sw_if_index,
4824 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004825 FIB_TEST((NULL == error), "Interface shutdown OK");
4826
4827 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4828 dpo = fib_entry_contribute_ip_forwarding(fei);
4829 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004830 "2001::b/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004831
4832 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4833 dpo = fib_entry_contribute_ip_forwarding(fei);
4834 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004835 "2001::a/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004836 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4837 dpo = fib_entry_contribute_ip_forwarding(fei);
4838 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004839 "2001:0:0:1::3/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004840 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4841 dpo = fib_entry_contribute_ip_forwarding(fei);
4842 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004843 "2001:0:0:1::2/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004844 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4845 dpo = fib_entry_contribute_ip_forwarding(fei);
4846 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004847 "2001:0:0:1::1/128 not drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004848 local_pfx.fp_len = 64;
4849 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4850 dpo = fib_entry_contribute_ip_forwarding(fei);
4851 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004852 "2001:0:0:1/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004853
4854 /*
4855 * no change
4856 */
4857 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004858 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004859 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004860 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004861 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004862 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004863
4864 /*
4865 * shutdown one of the other interfaces, then add a connected.
4866 * and swap one of the routes to it.
4867 */
4868 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004869 tm->hw[1]->sw_if_index,
4870 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004871 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4872
4873 fib_prefix_t connected_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004874 .fp_len = 64,
4875 .fp_proto = FIB_PROTOCOL_IP6,
4876 .fp_addr = {
4877 .ip6 = {
4878 /* 2001:0:0:2::1/64 */
4879 .as_u64 = {
4880 [0] = clib_host_to_net_u64(0x2001000000000002),
4881 [1] = clib_host_to_net_u64(0x0000000000000001),
4882 },
4883 },
4884 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004885 };
4886 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004887 FIB_SOURCE_INTERFACE,
4888 (FIB_ENTRY_FLAG_CONNECTED |
4889 FIB_ENTRY_FLAG_ATTACHED),
4890 DPO_PROTO_IP6,
4891 NULL,
4892 tm->hw[1]->sw_if_index,
4893 ~0,
4894 1,
4895 NULL,
4896 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004897 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4898 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4899 dpo = fib_entry_contribute_ip_forwarding(fei);
4900 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4901 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4902 "2001:0:0:2/64 not resolves via drop");
4903
4904 connected_pfx.fp_len = 128;
4905 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004906 FIB_SOURCE_INTERFACE,
4907 (FIB_ENTRY_FLAG_CONNECTED |
4908 FIB_ENTRY_FLAG_LOCAL),
4909 DPO_PROTO_IP6,
4910 NULL,
4911 tm->hw[0]->sw_if_index,
4912 ~0, // invalid fib index
4913 1,
4914 NULL,
4915 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004916 fei = fib_table_lookup(fib_index, &connected_pfx);
4917
4918 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4919 dpo = fib_entry_contribute_ip_forwarding(fei);
4920 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4921 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004922 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004923 rd = receive_dpo_get(dpo->dpoi_index);
4924 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004925 &rd->rd_addr)),
4926 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004927
4928 /*
4929 * +2 entries, +2 unshared path-lists
4930 */
4931 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004932 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004933 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004934 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004935 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004936 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004937
4938
4939 /*
4940 * bring the interface back up. we expected the routes to return
4941 * to normal forwarding.
4942 */
4943 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004944 tm->hw[0]->sw_if_index,
4945 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004946 FIB_TEST((NULL == error), "Interface bring-up OK");
4947 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4948 ai = fib_entry_get_adj(fei);
4949 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4950 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4951 ai = fib_entry_get_adj(fei);
4952 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4953 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4954 ai = fib_entry_get_adj(fei);
4955 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4956 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4957 ai = fib_entry_get_adj(fei);
4958 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4959 local_pfx.fp_len = 64;
4960 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4961 ai = fib_entry_get_adj(fei);
4962 adj = adj_get(ai);
4963 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004964 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004965
4966 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004967 * Same test as above, but this time the HW interface goes down
4968 */
4969 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004970 tm->hw_if_indicies[0],
4971 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00004972 FIB_TEST((NULL == error), "Interface shutdown OK");
4973
4974 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4975 dpo = fib_entry_contribute_ip_forwarding(fei);
4976 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004977 "2001::b/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004978 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4979 dpo = fib_entry_contribute_ip_forwarding(fei);
4980 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004981 "2001::a/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004982 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4983 dpo = fib_entry_contribute_ip_forwarding(fei);
4984 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004985 "2001:0:0:1::3/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004986 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4987 dpo = fib_entry_contribute_ip_forwarding(fei);
4988 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004989 "2001:0:0:1::2/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004990 local_pfx.fp_len = 128;
4991 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4992 dpo = fib_entry_contribute_ip_forwarding(fei);
4993 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004994 "2001:0:0:1::1/128 not drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004995 local_pfx.fp_len = 64;
4996 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4997 dpo = fib_entry_contribute_ip_forwarding(fei);
4998 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004999 "2001:0:0:1/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00005000
5001 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005002 tm->hw_if_indicies[0],
5003 VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00005004 FIB_TEST((NULL == error), "Interface bring-up OK");
5005 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5006 ai = fib_entry_get_adj(fei);
5007 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
5008 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5009 ai = fib_entry_get_adj(fei);
5010 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
5011 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5012 ai = fib_entry_get_adj(fei);
5013 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
5014 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5015 ai = fib_entry_get_adj(fei);
5016 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
5017 local_pfx.fp_len = 64;
5018 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5019 ai = fib_entry_get_adj(fei);
5020 adj = adj_get(ai);
5021 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08005022 "attached interface adj is glean");
Neale Ranns8b37b872016-11-21 12:25:22 +00005023
5024 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005025 * Delete the interface that the routes reolve through.
5026 * Again no routes are removed. They all point to drop.
5027 *
5028 * This is considered an error case. The control plane should
5029 * not remove interfaces through which routes resolve, but
5030 * such things can happen. ALL affected routes will drop.
5031 */
5032 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
5033
5034 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5035 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5036 "2001::b/64 resolves via drop");
5037 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5038 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5039 "2001::b/64 resolves via drop");
5040 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5041 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5042 "2001:0:0:1::3/64 resolves via drop");
5043 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5044 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5045 "2001:0:0:1::2/64 resolves via drop");
5046 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5047 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5048 "2001:0:0:1::1/128 is drop");
5049 local_pfx.fp_len = 64;
5050 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5051 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5052 "2001:0:0:1/64 resolves via drop");
5053
5054 /*
5055 * no change
5056 */
5057 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005058 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005059 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005060 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005061 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005062 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005063
5064 /*
5065 * Add the interface back. routes stay unresolved.
5066 */
5067 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005068 test_interface_device_class.index,
5069 0 /* instance */,
5070 hw_address,
5071 &tm->hw_if_indicies[0],
5072 /* flag change */ 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005073
5074 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5075 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5076 "2001::b/64 resolves via drop");
5077 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5078 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5079 "2001::b/64 resolves via drop");
5080 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5081 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5082 "2001:0:0:1::3/64 resolves via drop");
5083 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5084 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5085 "2001:0:0:1::2/64 resolves via drop");
5086 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5087 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5088 "2001:0:0:1::1/128 is drop");
5089 local_pfx.fp_len = 64;
5090 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5091 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5092 "2001:0:0:1/64 resolves via drop");
5093
5094 /*
5095 * CLEANUP ALL the routes
5096 */
5097 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005098 &pfx_2001_c_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_a_s_64,
5102 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005103 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005104 &pfx_2001_b_s_64,
5105 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005106 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005107 &pfx_2001_1_3_s_128,
5108 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005109 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005110 &pfx_2001_1_2_s_128,
5111 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005112 local_pfx.fp_len = 64;
5113 fib_table_entry_delete(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005114 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005115 local_pfx.fp_len = 128;
5116 fib_table_entry_special_remove(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005117 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005118 connected_pfx.fp_len = 64;
5119 fib_table_entry_delete(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005120 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005121 connected_pfx.fp_len = 128;
5122 fib_table_entry_special_remove(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005123 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005124
5125 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005126 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5127 "2001::a/64 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_b_s_64)),
5130 "2001::b/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005131 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005132 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128)),
5133 "2001:0:0:1::3/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005134 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005135 fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128)),
5136 "2001:0:0:1::3/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005137 local_pfx.fp_len = 64;
5138 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005139 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5140 "2001:0:0:1/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005141 local_pfx.fp_len = 128;
5142 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005143 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5144 "2001:0:0:1::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005145 connected_pfx.fp_len = 64;
5146 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005147 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5148 "2001:0:0:2/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005149 connected_pfx.fp_len = 128;
5150 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005151 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5152 "2001:0:0:2::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005153
5154 /*
5155 * -8 entries. -7 path-lists (1 was shared).
5156 */
5157 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005158 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005159 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005160 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005161 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005162 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005163
5164 /*
5165 * now remove the VRF
5166 */
Neale Ranns15002542017-09-10 04:39:11 -07005167 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005168
5169 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005170 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005171 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005172 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005173 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005174 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005175
5176 adj_unlock(ai_02);
5177 adj_unlock(ai_01);
5178
5179 /*
5180 * return the interfaces to up state
5181 */
5182 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005183 tm->hw[0]->sw_if_index,
5184 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005185 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005186 tm->hw[1]->sw_if_index,
5187 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005188
5189 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005190 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005191
Neale Ranns2303cb12018-02-21 04:57:17 -08005192 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005193}
5194
5195/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005196 * Test Attached Exports
5197 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005198static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005199fib_test_ae (void)
5200{
5201 const dpo_id_t *dpo, *dpo_drop;
5202 const u32 fib_index = 0;
5203 fib_node_index_t fei;
5204 test_main_t *tm;
5205 ip4_main_t *im;
Neale Ranns2303cb12018-02-21 04:57:17 -08005206 int res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005207
Neale Ranns2303cb12018-02-21 04:57:17 -08005208 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005209 tm = &test_main;
5210 im = &ip4_main;
5211
5212 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005213 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005214
5215 /*
5216 * add interface routes. We'll assume this works. It's more rigorously
5217 * tested elsewhere.
5218 */
5219 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005220 .fp_len = 24,
5221 .fp_proto = FIB_PROTOCOL_IP4,
5222 .fp_addr = {
5223 .ip4 = {
5224 /* 10.10.10.10 */
5225 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5226 },
5227 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005228 };
5229
5230 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5231 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5232
5233 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5234
5235 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005236 FIB_SOURCE_INTERFACE,
5237 (FIB_ENTRY_FLAG_CONNECTED |
5238 FIB_ENTRY_FLAG_ATTACHED),
5239 DPO_PROTO_IP4,
5240 NULL,
5241 tm->hw[0]->sw_if_index,
5242 ~0,
5243 1,
5244 NULL,
5245 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005246 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5247 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005248 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005249
5250 local_pfx.fp_len = 32;
5251 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005252 FIB_SOURCE_INTERFACE,
5253 (FIB_ENTRY_FLAG_CONNECTED |
5254 FIB_ENTRY_FLAG_LOCAL),
5255 DPO_PROTO_IP4,
5256 NULL,
5257 tm->hw[0]->sw_if_index,
5258 ~0, // invalid fib index
5259 1,
5260 NULL,
5261 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005262 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5263
5264 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005265 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005266
5267 /*
5268 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5269 */
5270 fib_prefix_t pfx_10_10_10_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005271 .fp_len = 32,
5272 .fp_proto = FIB_PROTOCOL_IP4,
5273 .fp_addr = {
5274 /* 10.10.10.1 */
5275 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5276 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005277 };
5278 fib_node_index_t ai;
5279
Neale Ranns81424992017-05-18 03:03:22 -07005280 fib_table_entry_path_add(fib_index,
5281 &pfx_10_10_10_1_s_32,
5282 FIB_SOURCE_ADJ,
5283 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005284 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005285 &pfx_10_10_10_1_s_32.fp_addr,
5286 tm->hw[0]->sw_if_index,
5287 ~0, // invalid fib index
5288 1,
5289 NULL,
5290 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005291
5292 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5293 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5294 ai = fib_entry_get_adj(fei);
5295
5296 /*
5297 * create another FIB table into which routes will be imported
5298 */
5299 u32 import_fib_index1;
5300
Neale Ranns15002542017-09-10 04:39:11 -07005301 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5302 11,
5303 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005304
5305 /*
5306 * Add an attached route in the import FIB
5307 */
5308 local_pfx.fp_len = 24;
5309 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005310 &local_pfx,
5311 FIB_SOURCE_API,
5312 FIB_ENTRY_FLAG_NONE,
5313 DPO_PROTO_IP4,
5314 NULL,
5315 tm->hw[0]->sw_if_index,
5316 ~0, // invalid fib index
5317 1,
5318 NULL,
5319 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005320 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5321 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5322
5323 /*
5324 * check for the presence of the adj-fibs in the import table
5325 */
5326 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5327 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5328 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005329 "adj-fib1 Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005330
5331 /*
5332 * check for the presence of the local in the import table
5333 */
5334 local_pfx.fp_len = 32;
5335 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5336 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5337
5338 /*
5339 * Add another adj-fin in the export table. Expect this
5340 * to get magically exported;
5341 */
5342 fib_prefix_t pfx_10_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005343 .fp_len = 32,
5344 .fp_proto = FIB_PROTOCOL_IP4,
5345 .fp_addr = {
5346 /* 10.10.10.2 */
5347 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5348 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005349 };
5350
Neale Ranns81424992017-05-18 03:03:22 -07005351 fib_table_entry_path_add(fib_index,
5352 &pfx_10_10_10_2_s_32,
5353 FIB_SOURCE_ADJ,
5354 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005355 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005356 &pfx_10_10_10_2_s_32.fp_addr,
5357 tm->hw[0]->sw_if_index,
5358 ~0, // invalid fib index
5359 1,
5360 NULL,
5361 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005362 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5363 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5364 ai = fib_entry_get_adj(fei);
5365
5366 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5367 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5368 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005369 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005370 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5371 "ADJ-fib2 imported flags %d",
5372 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005373
5374 /*
5375 * create a 2nd FIB table into which routes will be imported
5376 */
5377 u32 import_fib_index2;
5378
Neale Ranns15002542017-09-10 04:39:11 -07005379 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5380 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005381
5382 /*
5383 * Add an attached route in the import FIB
5384 */
5385 local_pfx.fp_len = 24;
5386 fib_table_entry_update_one_path(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005387 &local_pfx,
5388 FIB_SOURCE_API,
5389 FIB_ENTRY_FLAG_NONE,
5390 DPO_PROTO_IP4,
5391 NULL,
5392 tm->hw[0]->sw_if_index,
5393 ~0, // invalid fib index
5394 1,
5395 NULL,
5396 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005397 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5398 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5399
5400 /*
5401 * check for the presence of all the adj-fibs and local in the import table
5402 */
5403 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5404 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5405 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5406 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5407 local_pfx.fp_len = 32;
5408 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5409 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5410
5411 /*
5412 * add a 3rd adj-fib. expect it to be exported to both tables.
5413 */
5414 fib_prefix_t pfx_10_10_10_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005415 .fp_len = 32,
5416 .fp_proto = FIB_PROTOCOL_IP4,
5417 .fp_addr = {
5418 /* 10.10.10.3 */
5419 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5420 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005421 };
5422
Neale Ranns81424992017-05-18 03:03:22 -07005423 fib_table_entry_path_add(fib_index,
5424 &pfx_10_10_10_3_s_32,
5425 FIB_SOURCE_ADJ,
5426 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005427 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005428 &pfx_10_10_10_3_s_32.fp_addr,
5429 tm->hw[0]->sw_if_index,
5430 ~0, // invalid fib index
5431 1,
5432 NULL,
5433 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005434 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5435 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5436 ai = fib_entry_get_adj(fei);
5437
5438 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5439 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5440 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005441 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005442 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5443 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5444 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005445 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005446
5447 /*
5448 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5449 */
5450 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005451 &pfx_10_10_10_3_s_32,
5452 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005453
5454 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5455 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5456
5457 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5458 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5459
5460 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5461 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5462
5463 /*
5464 * remove the attached route from the 2nd FIB. expect the imported
5465 * entires to be removed
5466 */
5467 local_pfx.fp_len = 24;
5468 fib_table_entry_delete(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005469 &local_pfx,
5470 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005471 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5472 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5473
5474 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5475 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5476 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5477 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5478 local_pfx.fp_len = 32;
5479 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5480 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5481
5482 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5483 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5484 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5485 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5486 local_pfx.fp_len = 32;
5487 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5488 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5489
5490 /*
5491 * modify the route in FIB1 so it is no longer attached. expect the imported
5492 * entires to be removed
5493 */
5494 local_pfx.fp_len = 24;
5495 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005496 &local_pfx,
5497 FIB_SOURCE_API,
5498 FIB_ENTRY_FLAG_NONE,
5499 DPO_PROTO_IP4,
5500 &pfx_10_10_10_2_s_32.fp_addr,
5501 tm->hw[0]->sw_if_index,
5502 ~0, // invalid fib index
5503 1,
5504 NULL,
5505 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005506 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5507 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5508 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5509 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5510 local_pfx.fp_len = 32;
5511 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5512 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5513
5514 /*
5515 * modify it back to attached. expect the adj-fibs back
5516 */
5517 local_pfx.fp_len = 24;
5518 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005519 &local_pfx,
5520 FIB_SOURCE_API,
5521 FIB_ENTRY_FLAG_NONE,
5522 DPO_PROTO_IP4,
5523 NULL,
5524 tm->hw[0]->sw_if_index,
5525 ~0, // invalid fib index
5526 1,
5527 NULL,
5528 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005529 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5530 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5531 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5532 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5533 local_pfx.fp_len = 32;
5534 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5535 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5536
5537 /*
5538 * add a covering attached next-hop for the interface address, so we have
5539 * a valid adj to find when we check the forwarding tables
5540 */
5541 fib_prefix_t pfx_10_0_0_0_s_8 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005542 .fp_len = 8,
5543 .fp_proto = FIB_PROTOCOL_IP4,
5544 .fp_addr = {
5545 /* 10.0.0.0 */
5546 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5547 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005548 };
5549
5550 fei = fib_table_entry_update_one_path(fib_index,
5551 &pfx_10_0_0_0_s_8,
5552 FIB_SOURCE_API,
5553 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005554 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005555 &pfx_10_10_10_3_s_32.fp_addr,
5556 tm->hw[0]->sw_if_index,
5557 ~0, // invalid fib index
5558 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005559 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005560 FIB_ROUTE_PATH_FLAG_NONE);
5561 dpo = fib_entry_contribute_ip_forwarding(fei);
5562
5563 /*
5564 * remove the route in the export fib. expect the adj-fibs to be removed
5565 */
5566 local_pfx.fp_len = 24;
5567 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005568 &local_pfx,
5569 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005570
5571 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5572 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5573 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5574 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5575 local_pfx.fp_len = 32;
5576 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5577 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5578
5579 /*
5580 * the adj-fibs in the export VRF are present in the FIB table,
5581 * but not installed in forwarding, since they have no attached cover.
5582 * Consequently a lookup in the MTRIE gives the adj for the covering
5583 * route 10.0.0.0/8.
5584 */
5585 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5586 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5587
5588 index_t lbi;
5589 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5590 FIB_TEST(lbi == dpo->dpoi_index,
5591 "10.10.10.1 forwards on \n%U not \n%U",
5592 format_load_balance, lbi, 0,
5593 format_dpo_id, dpo, 0);
5594 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5595 FIB_TEST(lbi == dpo->dpoi_index,
5596 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5597 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5598 FIB_TEST(lbi == dpo->dpoi_index,
5599 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5600
5601 /*
5602 * add the export prefix back, but not as attached.
5603 * No adj-fibs in export nor import tables
5604 */
5605 local_pfx.fp_len = 24;
5606 fei = fib_table_entry_update_one_path(fib_index,
5607 &local_pfx,
5608 FIB_SOURCE_API,
5609 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005610 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005611 &pfx_10_10_10_1_s_32.fp_addr,
5612 tm->hw[0]->sw_if_index,
5613 ~0, // invalid fib index
5614 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005615 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005616 FIB_ROUTE_PATH_FLAG_NONE);
5617 dpo = fib_entry_contribute_ip_forwarding(fei);
5618
5619 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5620 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5621 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5622 FIB_TEST(lbi == dpo->dpoi_index,
5623 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5624 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5625 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5626 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5627 FIB_TEST(lbi == dpo->dpoi_index,
5628 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5629
5630 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5631 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5632 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5633 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5634 local_pfx.fp_len = 32;
5635 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5636 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5637
5638 /*
5639 * modify the export prefix so it is attached. expect all covereds to return
5640 */
5641 local_pfx.fp_len = 24;
5642 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005643 &local_pfx,
5644 FIB_SOURCE_API,
5645 FIB_ENTRY_FLAG_NONE,
5646 DPO_PROTO_IP4,
5647 NULL,
5648 tm->hw[0]->sw_if_index,
5649 ~0, // invalid fib index
5650 1,
5651 NULL,
5652 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005653
5654 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5655 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5656 dpo = fib_entry_contribute_ip_forwarding(fei);
5657 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005658 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005659 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5660 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5661 local_pfx.fp_len = 32;
5662 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5663 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5664 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5665 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5666 dpo = fib_entry_contribute_ip_forwarding(fei);
5667 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005668 "Adj-fib1 is not drop in export: %U %U",
5669 format_dpo_id, dpo, 0,
5670 format_dpo_id, load_balance_get_bucket(dpo->dpoi_index, 0), 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005671 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5672 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5673 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5674 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5675 local_pfx.fp_len = 32;
5676 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5677 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5678
5679 /*
5680 * modify the export prefix so connected. no change.
5681 */
5682 local_pfx.fp_len = 24;
5683 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005684 FIB_SOURCE_INTERFACE,
5685 (FIB_ENTRY_FLAG_CONNECTED |
5686 FIB_ENTRY_FLAG_ATTACHED),
5687 DPO_PROTO_IP4,
5688 NULL,
5689 tm->hw[0]->sw_if_index,
5690 ~0,
5691 1,
5692 NULL,
5693 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005694
5695 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5696 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5697 dpo = fib_entry_contribute_ip_forwarding(fei);
5698 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005699 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005700 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5701 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5702 local_pfx.fp_len = 32;
5703 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5704 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5705 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5706 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5707 dpo = fib_entry_contribute_ip_forwarding(fei);
5708 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005709 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005710 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5711 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5712 local_pfx.fp_len = 32;
5713 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5714 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5715
5716 /*
5717 * CLEANUP
5718 */
5719 fib_table_entry_delete(fib_index,
5720 &pfx_10_0_0_0_s_8,
5721 FIB_SOURCE_API);
5722 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005723 &pfx_10_10_10_1_s_32,
5724 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005725 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005726 &pfx_10_10_10_2_s_32,
5727 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005728 local_pfx.fp_len = 32;
5729 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005730 &local_pfx,
5731 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005732 local_pfx.fp_len = 24;
5733 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005734 &local_pfx,
5735 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005736 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005737 &local_pfx,
5738 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005739 local_pfx.fp_len = 24;
5740 fib_table_entry_delete(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005741 &local_pfx,
5742 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005743
Neale Ranns15002542017-09-10 04:39:11 -07005744 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5745 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005746
5747 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005748 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005749
Neale Ranns2303cb12018-02-21 04:57:17 -08005750 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005751}
5752
Neale Ranns57b58602017-07-15 07:37:25 -07005753/*
5754 * Test Path Preference
5755 */
5756static int
5757fib_test_pref (void)
5758{
5759 test_main_t *tm = &test_main;
Neale Ranns2303cb12018-02-21 04:57:17 -08005760 int res;
Neale Ranns57b58602017-07-15 07:37:25 -07005761
Neale Ranns2303cb12018-02-21 04:57:17 -08005762 res = 0;
Neale Ranns57b58602017-07-15 07:37:25 -07005763 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5764 .fp_len = 32,
5765 .fp_proto = FIB_PROTOCOL_IP4,
5766 .fp_addr = {
5767 .ip4 = {
5768 .as_u32 = clib_host_to_net_u32(0x01010101),
5769 },
5770 },
5771 };
5772
5773 /*
5774 * 2 high, 2 medium and 2 low preference non-recursive paths
5775 */
5776 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005777 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005778 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5779 .frp_fib_index = ~0,
5780 .frp_weight = 1,
5781 .frp_preference = 0,
5782 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5783 .frp_addr = {
5784 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5785 },
5786 };
5787 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005788 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005789 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5790 .frp_fib_index = ~0,
5791 .frp_weight = 1,
5792 .frp_preference = 0,
5793 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5794 .frp_addr = {
5795 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5796 },
5797 };
5798 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005799 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005800 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5801 .frp_fib_index = ~0,
5802 .frp_weight = 1,
5803 .frp_preference = 1,
5804 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5805 .frp_addr = {
5806 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5807 },
5808 };
5809 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005810 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005811 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5812 .frp_fib_index = ~0,
5813 .frp_weight = 1,
5814 .frp_preference = 1,
5815 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5816 .frp_addr = {
5817 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5818 },
5819 };
5820 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005821 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005822 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5823 .frp_fib_index = ~0,
5824 .frp_weight = 1,
5825 .frp_preference = 2,
5826 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5827 .frp_addr = {
5828 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5829 },
5830 };
5831 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005832 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005833 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5834 .frp_fib_index = ~0,
5835 .frp_weight = 1,
5836 .frp_preference = 2,
5837 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5838 .frp_addr = {
5839 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5840 },
5841 };
5842 fib_route_path_t *nr_paths = NULL;
5843
5844 vec_add1(nr_paths, nr_path_hi_1);
5845 vec_add1(nr_paths, nr_path_hi_2);
5846 vec_add1(nr_paths, nr_path_med_1);
5847 vec_add1(nr_paths, nr_path_med_2);
5848 vec_add1(nr_paths, nr_path_low_1);
5849 vec_add1(nr_paths, nr_path_low_2);
5850
5851 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5852 VNET_LINK_IP4,
5853 &nr_path_hi_1.frp_addr,
5854 nr_path_hi_1.frp_sw_if_index);
5855 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5856 VNET_LINK_IP4,
5857 &nr_path_hi_2.frp_addr,
5858 nr_path_hi_2.frp_sw_if_index);
5859 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5860 VNET_LINK_IP4,
5861 &nr_path_med_1.frp_addr,
5862 nr_path_med_1.frp_sw_if_index);
5863 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5864 VNET_LINK_IP4,
5865 &nr_path_med_2.frp_addr,
5866 nr_path_med_2.frp_sw_if_index);
5867 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5868 VNET_LINK_IP4,
5869 &nr_path_low_1.frp_addr,
5870 nr_path_low_1.frp_sw_if_index);
5871 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5872 VNET_LINK_IP4,
5873 &nr_path_low_2.frp_addr,
5874 nr_path_low_2.frp_sw_if_index);
5875
5876 fib_test_lb_bucket_t ip_hi_1 = {
5877 .type = FT_LB_ADJ,
5878 .adj = {
5879 .adj = ai_hi_1,
5880 },
5881 };
5882 fib_test_lb_bucket_t ip_hi_2 = {
5883 .type = FT_LB_ADJ,
5884 .adj = {
5885 .adj = ai_hi_2,
5886 },
5887 };
5888 fib_test_lb_bucket_t ip_med_1 = {
5889 .type = FT_LB_ADJ,
5890 .adj = {
5891 .adj = ai_med_1,
5892 },
5893 };
5894 fib_test_lb_bucket_t ip_med_2 = {
5895 .type = FT_LB_ADJ,
5896 .adj = {
5897 .adj = ai_med_2,
5898 },
5899 };
5900 fib_test_lb_bucket_t ip_low_1 = {
5901 .type = FT_LB_ADJ,
5902 .adj = {
5903 .adj = ai_low_1,
5904 },
5905 };
5906 fib_test_lb_bucket_t ip_low_2 = {
5907 .type = FT_LB_ADJ,
5908 .adj = {
5909 .adj = ai_low_2,
5910 },
5911 };
5912
5913 fib_node_index_t fei;
5914
5915 fei = fib_table_entry_path_add2(0,
5916 &pfx_1_1_1_1_s_32,
5917 FIB_SOURCE_API,
5918 FIB_ENTRY_FLAG_NONE,
5919 nr_paths);
5920
Neale Ranns2303cb12018-02-21 04:57:17 -08005921 FIB_TEST(!fib_test_validate_entry(fei,
5922 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5923 2,
5924 &ip_hi_1,
5925 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005926 "1.1.1.1/32 via high preference paths");
5927
5928 /*
5929 * bring down the interface on which the high preference path lie
5930 */
5931 vnet_sw_interface_set_flags(vnet_get_main(),
5932 tm->hw[0]->sw_if_index,
5933 0);
5934
Neale Ranns2303cb12018-02-21 04:57:17 -08005935 FIB_TEST(!fib_test_validate_entry(fei,
5936 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5937 2,
5938 &ip_med_1,
5939 &ip_med_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005940 "1.1.1.1/32 via medium preference paths");
5941
5942 /*
5943 * bring down the interface on which the medium preference path lie
5944 */
5945 vnet_sw_interface_set_flags(vnet_get_main(),
5946 tm->hw[1]->sw_if_index,
5947 0);
5948
Neale Ranns2303cb12018-02-21 04:57:17 -08005949 FIB_TEST(!fib_test_validate_entry(fei,
5950 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5951 2,
5952 &ip_low_1,
5953 &ip_low_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005954 "1.1.1.1/32 via low preference paths");
5955
5956 /*
5957 * bring up the interface on which the high preference path lie
5958 */
5959 vnet_sw_interface_set_flags(vnet_get_main(),
5960 tm->hw[0]->sw_if_index,
5961 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5962
Neale Ranns2303cb12018-02-21 04:57:17 -08005963 FIB_TEST(!fib_test_validate_entry(fei,
5964 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5965 2,
5966 &ip_hi_1,
5967 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005968 "1.1.1.1/32 via high preference paths");
5969
5970 /*
5971 * bring up the interface on which the medium preference path lie
5972 */
5973 vnet_sw_interface_set_flags(vnet_get_main(),
5974 tm->hw[1]->sw_if_index,
5975 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5976
Neale Ranns2303cb12018-02-21 04:57:17 -08005977 FIB_TEST(!fib_test_validate_entry(fei,
5978 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5979 2,
5980 &ip_hi_1,
5981 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005982 "1.1.1.1/32 via high preference paths");
5983
5984 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5985 fib_entry_contribute_forwarding(fei,
5986 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5987 &ip_1_1_1_1);
5988
5989 /*
5990 * 3 recursive paths of different preference
5991 */
5992 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5993 .fp_len = 32,
5994 .fp_proto = FIB_PROTOCOL_IP4,
5995 .fp_addr = {
5996 .ip4 = {
5997 .as_u32 = clib_host_to_net_u32(0x01010102),
5998 },
5999 },
6000 };
6001 const fib_prefix_t pfx_1_1_1_3_s_32 = {
6002 .fp_len = 32,
6003 .fp_proto = FIB_PROTOCOL_IP4,
6004 .fp_addr = {
6005 .ip4 = {
6006 .as_u32 = clib_host_to_net_u32(0x01010103),
6007 },
6008 },
6009 };
6010 fei = fib_table_entry_path_add2(0,
6011 &pfx_1_1_1_2_s_32,
6012 FIB_SOURCE_API,
6013 FIB_ENTRY_FLAG_NONE,
6014 nr_paths);
6015 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
6016 fib_entry_contribute_forwarding(fei,
6017 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6018 &ip_1_1_1_2);
6019 fei = fib_table_entry_path_add2(0,
6020 &pfx_1_1_1_3_s_32,
6021 FIB_SOURCE_API,
6022 FIB_ENTRY_FLAG_NONE,
6023 nr_paths);
6024 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
6025 fib_entry_contribute_forwarding(fei,
6026 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6027 &ip_1_1_1_3);
6028
6029 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
6030 .type = FT_LB_O_LB,
6031 .lb = {
6032 .lb = ip_1_1_1_1.dpoi_index,
6033 },
6034 };
6035 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
6036 .type = FT_LB_O_LB,
6037 .lb = {
6038 .lb = ip_1_1_1_2.dpoi_index,
6039 },
6040 };
6041 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
6042 .type = FT_LB_O_LB,
6043 .lb = {
6044 .lb = ip_1_1_1_3.dpoi_index,
6045 },
6046 };
6047 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07006048 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006049 .frp_sw_if_index = ~0,
6050 .frp_fib_index = 0,
6051 .frp_weight = 1,
6052 .frp_preference = 0,
6053 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6054 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6055 };
6056 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006057 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006058 .frp_sw_if_index = ~0,
6059 .frp_fib_index = 0,
6060 .frp_weight = 1,
6061 .frp_preference = 10,
6062 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6063 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6064 };
6065 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006066 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006067 .frp_sw_if_index = ~0,
6068 .frp_fib_index = 0,
6069 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006070 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006071 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6072 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6073 };
6074 fib_route_path_t *r_paths = NULL;
6075
6076 vec_add1(r_paths, r_path_hi);
6077 vec_add1(r_paths, r_path_low);
6078 vec_add1(r_paths, r_path_med);
6079
6080 /*
6081 * add many recursive so we get the LB MAp created
6082 */
Neale Ranns2303cb12018-02-21 04:57:17 -08006083#define N_PFXS 64
Neale Ranns57b58602017-07-15 07:37:25 -07006084 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006085 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006086 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6087 {
6088 pfx_r[n_pfxs].fp_len = 32;
6089 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6090 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6091 clib_host_to_net_u32(0x02000000 + n_pfxs);
6092
6093 fei = fib_table_entry_path_add2(0,
6094 &pfx_r[n_pfxs],
6095 FIB_SOURCE_API,
6096 FIB_ENTRY_FLAG_NONE,
6097 r_paths);
6098
Neale Ranns2303cb12018-02-21 04:57:17 -08006099 FIB_TEST(!fib_test_validate_entry(fei,
6100 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6101 1,
6102 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006103 "recursive via high preference paths");
6104
6105 /*
6106 * withdraw hig pref resolving entry
6107 */
6108 fib_table_entry_delete(0,
6109 &pfx_1_1_1_1_s_32,
6110 FIB_SOURCE_API);
6111
6112 /* suspend so the update walk kicks int */
6113 vlib_process_suspend(vlib_get_main(), 1e-5);
6114
Neale Ranns2303cb12018-02-21 04:57:17 -08006115 FIB_TEST(!fib_test_validate_entry(fei,
6116 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6117 1,
6118 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006119 "recursive via medium preference paths");
6120
6121 /*
6122 * withdraw medium pref resolving entry
6123 */
6124 fib_table_entry_delete(0,
6125 &pfx_1_1_1_2_s_32,
6126 FIB_SOURCE_API);
6127
6128 /* suspend so the update walk kicks int */
6129 vlib_process_suspend(vlib_get_main(), 1e-5);
6130
Neale Ranns2303cb12018-02-21 04:57:17 -08006131 FIB_TEST(!fib_test_validate_entry(fei,
6132 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6133 1,
6134 &ip_o_1_1_1_3),
Neale Ranns57b58602017-07-15 07:37:25 -07006135 "recursive via low preference paths");
6136
6137 /*
6138 * add back paths for next iteration
6139 */
6140 fei = fib_table_entry_update(0,
6141 &pfx_1_1_1_2_s_32,
6142 FIB_SOURCE_API,
6143 FIB_ENTRY_FLAG_NONE,
6144 nr_paths);
6145 fei = fib_table_entry_update(0,
6146 &pfx_1_1_1_1_s_32,
6147 FIB_SOURCE_API,
6148 FIB_ENTRY_FLAG_NONE,
6149 nr_paths);
6150
6151 /* suspend so the update walk kicks int */
6152 vlib_process_suspend(vlib_get_main(), 1e-5);
6153
6154 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
Neale Ranns2303cb12018-02-21 04:57:17 -08006155 FIB_TEST(!fib_test_validate_entry(fei,
6156 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6157 1,
6158 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006159 "recursive via high preference paths");
6160 }
6161
6162
6163 fib_table_entry_delete(0,
6164 &pfx_1_1_1_1_s_32,
6165 FIB_SOURCE_API);
6166
6167 /* suspend so the update walk kicks int */
6168 vlib_process_suspend(vlib_get_main(), 1e-5);
6169
6170 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6171 {
6172 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6173
Neale Ranns2303cb12018-02-21 04:57:17 -08006174 FIB_TEST(!fib_test_validate_entry(fei,
6175 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6176 1,
6177 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006178 "recursive via medium preference paths");
6179 }
6180 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6181 {
6182 fib_table_entry_delete(0,
6183 &pfx_r[n_pfxs],
6184 FIB_SOURCE_API);
6185 }
6186
6187 /*
6188 * Cleanup
6189 */
6190 fib_table_entry_delete(0,
6191 &pfx_1_1_1_2_s_32,
6192 FIB_SOURCE_API);
6193 fib_table_entry_delete(0,
6194 &pfx_1_1_1_3_s_32,
6195 FIB_SOURCE_API);
6196
6197 dpo_reset(&ip_1_1_1_1);
6198 dpo_reset(&ip_1_1_1_2);
6199 dpo_reset(&ip_1_1_1_3);
6200 adj_unlock(ai_low_2);
6201 adj_unlock(ai_low_1);
6202 adj_unlock(ai_med_2);
6203 adj_unlock(ai_med_1);
6204 adj_unlock(ai_hi_2);
6205 adj_unlock(ai_hi_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08006206
6207 return (res);
Neale Ranns57b58602017-07-15 07:37:25 -07006208}
Neale Rannsad422ed2016-11-02 14:20:04 +00006209
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006210/*
6211 * Test the recursive route route handling for GRE tunnels
6212 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006213static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006214fib_test_label (void)
6215{
6216 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;
6217 const u32 fib_index = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -08006218 int lb_count, ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006219 test_main_t *tm;
6220 ip4_main_t *im;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006221
Neale Ranns2303cb12018-02-21 04:57:17 -08006222 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006223 lb_count = pool_elts(load_balance_pool);
6224 tm = &test_main;
6225 im = &ip4_main;
6226
6227 /*
6228 * add interface routes. We'll assume this works. It's more rigorously
6229 * tested elsewhere.
6230 */
6231 fib_prefix_t local0_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006232 .fp_len = 24,
6233 .fp_proto = FIB_PROTOCOL_IP4,
6234 .fp_addr = {
6235 .ip4 = {
6236 /* 10.10.10.10 */
6237 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6238 },
6239 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006240 };
6241
6242 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08006243 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006244
6245 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6246 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6247
6248 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006249 FIB_SOURCE_INTERFACE,
6250 (FIB_ENTRY_FLAG_CONNECTED |
6251 FIB_ENTRY_FLAG_ATTACHED),
6252 DPO_PROTO_IP4,
6253 NULL,
6254 tm->hw[0]->sw_if_index,
6255 ~0,
6256 1,
6257 NULL,
6258 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006259 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6260 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006261 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006262
6263 local0_pfx.fp_len = 32;
6264 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006265 FIB_SOURCE_INTERFACE,
6266 (FIB_ENTRY_FLAG_CONNECTED |
6267 FIB_ENTRY_FLAG_LOCAL),
6268 DPO_PROTO_IP4,
6269 NULL,
6270 tm->hw[0]->sw_if_index,
6271 ~0, // invalid fib index
6272 1,
6273 NULL,
6274 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006275 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6276
6277 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006278 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006279
6280 fib_prefix_t local1_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006281 .fp_len = 24,
6282 .fp_proto = FIB_PROTOCOL_IP4,
6283 .fp_addr = {
6284 .ip4 = {
6285 /* 10.10.11.10 */
6286 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6287 },
6288 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006289 };
6290
6291 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6292 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6293
6294 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006295 FIB_SOURCE_INTERFACE,
6296 (FIB_ENTRY_FLAG_CONNECTED |
6297 FIB_ENTRY_FLAG_ATTACHED),
6298 DPO_PROTO_IP4,
6299 NULL,
6300 tm->hw[1]->sw_if_index,
6301 ~0,
6302 1,
6303 NULL,
6304 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006305 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6306 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006307 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006308
6309 local1_pfx.fp_len = 32;
6310 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006311 FIB_SOURCE_INTERFACE,
6312 (FIB_ENTRY_FLAG_CONNECTED |
6313 FIB_ENTRY_FLAG_LOCAL),
6314 DPO_PROTO_IP4,
6315 NULL,
6316 tm->hw[1]->sw_if_index,
6317 ~0, // invalid fib index
6318 1,
6319 NULL,
6320 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006321 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6322
6323 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006324 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006325
6326 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006327 .ip4 = {
6328 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6329 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006330 };
6331 ip46_address_t nh_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006332 .ip4 = {
6333 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6334 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006335 };
6336 ip46_address_t nh_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006337 .ip4 = {
6338 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6339 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006340 };
6341
6342 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006343 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006344 &nh_10_10_11_1,
6345 tm->hw[1]->sw_if_index);
6346 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006347 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006348 &nh_10_10_11_2,
6349 tm->hw[1]->sw_if_index);
6350 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006351 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006352 &nh_10_10_10_1,
6353 tm->hw[0]->sw_if_index);
6354 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006355 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006356 &nh_10_10_11_2,
6357 tm->hw[1]->sw_if_index);
6358 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006359 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006360 &nh_10_10_11_1,
6361 tm->hw[1]->sw_if_index);
6362
6363 /*
6364 * Add an etry with one path with a real out-going label
6365 */
6366 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006367 .fp_len = 32,
6368 .fp_proto = FIB_PROTOCOL_IP4,
6369 .fp_addr = {
6370 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6371 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006372 };
6373 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006374 .type = FT_LB_LABEL_O_ADJ,
6375 .label_o_adj = {
6376 .adj = ai_mpls_10_10_10_1,
6377 .label = 99,
6378 .eos = MPLS_EOS,
6379 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006380 };
6381 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006382 .type = FT_LB_LABEL_O_ADJ,
6383 .label_o_adj = {
6384 .adj = ai_mpls_10_10_10_1,
6385 .label = 99,
6386 .eos = MPLS_NON_EOS,
6387 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006388 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006389 fib_mpls_label_t *l99 = NULL, fml99 = {
6390 .fml_value = 99,
6391 };
6392 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006393
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006394 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006395 &pfx_1_1_1_1_s_32,
6396 FIB_SOURCE_API,
6397 FIB_ENTRY_FLAG_NONE,
6398 DPO_PROTO_IP4,
6399 &nh_10_10_10_1,
6400 tm->hw[0]->sw_if_index,
6401 ~0, // invalid fib index
6402 1,
6403 l99,
6404 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006405
6406 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6407 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6408
Neale Ranns2303cb12018-02-21 04:57:17 -08006409 FIB_TEST(!fib_test_validate_entry(fei,
6410 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6411 1,
6412 &l99_eos_o_10_10_10_1),
6413 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006414
6415 /*
6416 * add a path with an implicit NULL label
6417 */
6418 fib_test_lb_bucket_t a_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006419 .type = FT_LB_ADJ,
6420 .adj = {
6421 .adj = ai_v4_10_10_11_1,
6422 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006423 };
6424 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006425 .type = FT_LB_ADJ,
6426 .adj = {
6427 .adj = ai_mpls_10_10_11_1,
6428 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006429 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006430 fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = {
6431 .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
6432 };
6433 vec_add1(l_imp_null, fml_imp_null);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006434
6435 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006436 &pfx_1_1_1_1_s_32,
6437 FIB_SOURCE_API,
6438 FIB_ENTRY_FLAG_NONE,
6439 DPO_PROTO_IP4,
6440 &nh_10_10_11_1,
6441 tm->hw[1]->sw_if_index,
6442 ~0, // invalid fib index
6443 1,
6444 l_imp_null,
6445 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006446
Neale Ranns2303cb12018-02-21 04:57:17 -08006447 FIB_TEST(!fib_test_validate_entry(fei,
6448 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6449 2,
6450 &l99_eos_o_10_10_10_1,
6451 &a_o_10_10_11_1),
6452 "1.1.1.1/32 LB 2 buckets via: "
6453 "label 99 over 10.10.10.1, "
6454 "adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006455
6456 /*
6457 * assign the route a local label
6458 */
6459 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006460 &pfx_1_1_1_1_s_32,
6461 24001);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006462
6463 fib_prefix_t pfx_24001_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006464 .fp_proto = FIB_PROTOCOL_MPLS,
6465 .fp_label = 24001,
6466 .fp_eos = MPLS_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006467 };
6468 fib_prefix_t pfx_24001_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006469 .fp_proto = FIB_PROTOCOL_MPLS,
6470 .fp_label = 24001,
6471 .fp_eos = MPLS_NON_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006472 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006473 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006474 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006475 .adj = {
6476 .adj = ai_v4_10_10_11_1,
6477 },
6478 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006479
6480 /*
6481 * The EOS entry should link to both the paths,
6482 * and use an ip adj for the imp-null
6483 * The NON-EOS entry should link to both the paths,
6484 * and use an mpls adj for the imp-null
6485 */
6486 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006487 &pfx_24001_eos);
6488 FIB_TEST(!fib_test_validate_entry(fei,
6489 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6490 2,
6491 &l99_eos_o_10_10_10_1,
6492 &disp_o_10_10_11_1),
6493 "24001/eos LB 2 buckets via: "
6494 "label 99 over 10.10.10.1, "
6495 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006496
6497
6498 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006499 &pfx_24001_neos);
6500 FIB_TEST(!fib_test_validate_entry(fei,
6501 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6502 2,
6503 &l99_neos_o_10_10_10_1,
6504 &a_mpls_o_10_10_11_1),
6505 "24001/neos LB 1 bucket via: "
6506 "label 99 over 10.10.10.1 ",
6507 "mpls-adj via 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006508
6509 /*
6510 * add an unlabelled path, this is excluded from the neos chains,
6511 */
6512 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006513 .type = FT_LB_ADJ,
6514 .adj = {
6515 .adj = ai_v4_10_10_11_2,
6516 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006517 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006518 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006519 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006520 .adj = {
6521 .adj = ai_v4_10_10_11_2,
6522 },
6523 };
6524
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006525
6526 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006527 &pfx_1_1_1_1_s_32,
6528 FIB_SOURCE_API,
6529 FIB_ENTRY_FLAG_NONE,
6530 DPO_PROTO_IP4,
6531 &nh_10_10_11_2,
6532 tm->hw[1]->sw_if_index,
6533 ~0, // invalid fib index
6534 1,
6535 NULL,
6536 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006537
Neale Ranns2303cb12018-02-21 04:57:17 -08006538 FIB_TEST(!fib_test_validate_entry(fei,
6539 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6540 16, // 3 choices spread over 16 buckets
6541 &l99_eos_o_10_10_10_1,
6542 &l99_eos_o_10_10_10_1,
6543 &l99_eos_o_10_10_10_1,
6544 &l99_eos_o_10_10_10_1,
6545 &l99_eos_o_10_10_10_1,
6546 &l99_eos_o_10_10_10_1,
6547 &a_o_10_10_11_1,
6548 &a_o_10_10_11_1,
6549 &a_o_10_10_11_1,
6550 &a_o_10_10_11_1,
6551 &a_o_10_10_11_1,
6552 &adj_o_10_10_11_2,
6553 &adj_o_10_10_11_2,
6554 &adj_o_10_10_11_2,
6555 &adj_o_10_10_11_2,
6556 &adj_o_10_10_11_2),
6557 "1.1.1.1/32 LB 16 buckets via: "
6558 "label 99 over 10.10.10.1, "
6559 "adj over 10.10.11.1",
6560 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006561
6562 /*
6563 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6564 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006565 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006566 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006567 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6568 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006569
6570 /*
6571 * n-eos has only the 2 labelled paths
6572 */
6573 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006574 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006575
Neale Ranns2303cb12018-02-21 04:57:17 -08006576 FIB_TEST(!fib_test_validate_entry(fei,
6577 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6578 2,
6579 &l99_neos_o_10_10_10_1,
6580 &a_mpls_o_10_10_11_1),
6581 "24001/neos LB 2 buckets via: "
6582 "label 99 over 10.10.10.1, "
6583 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006584
6585 /*
6586 * A labelled recursive
6587 */
6588 fib_prefix_t pfx_2_2_2_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006589 .fp_len = 32,
6590 .fp_proto = FIB_PROTOCOL_IP4,
6591 .fp_addr = {
6592 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6593 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006594 };
6595 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6596 .type = FT_LB_LABEL_O_LB,
6597 .label_o_lb = {
6598 .lb = non_eos_1_1_1_1.dpoi_index,
6599 .label = 1600,
6600 .eos = MPLS_EOS,
Neale Ranns31ed7442018-02-23 05:29:09 -08006601 .mode = FIB_MPLS_LSP_MODE_UNIFORM,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006602 },
6603 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006604 fib_mpls_label_t *l1600 = NULL, fml1600 = {
6605 .fml_value = 1600,
6606 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
6607 };
6608 vec_add1(l1600, fml1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006609
Neale Ranns31ed7442018-02-23 05:29:09 -08006610 fei = fib_table_entry_update_one_path(fib_index,
6611 &pfx_2_2_2_2_s_32,
6612 FIB_SOURCE_API,
6613 FIB_ENTRY_FLAG_NONE,
6614 DPO_PROTO_IP4,
6615 &pfx_1_1_1_1_s_32.fp_addr,
6616 ~0,
6617 fib_index,
6618 1,
6619 l1600,
6620 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006621
Neale Ranns2303cb12018-02-21 04:57:17 -08006622 FIB_TEST(!fib_test_validate_entry(fei,
6623 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6624 1,
6625 &l1600_eos_o_1_1_1_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006626 "2.2.2.2.2/32 LB 1 buckets via: "
6627 "label 1600 over 1.1.1.1");
6628
Neale Ranns948e00f2016-10-20 13:39:34 +01006629 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006630 index_t urpfi;
6631
6632 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6633 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6634
6635 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006636 "uRPF check for 2.2.2.2/32 on %d OK",
6637 tm->hw[0]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006638 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006639 "uRPF check for 2.2.2.2/32 on %d OK",
6640 tm->hw[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006641 FIB_TEST(!fib_urpf_check(urpfi, 99),
Neale Ranns2303cb12018-02-21 04:57:17 -08006642 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6643 99);
Neale Ranns3ee44042016-10-03 13:05:48 +01006644
6645 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6646 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006647 "Shared uRPF on IP and non-EOS chain");
Neale Ranns3ee44042016-10-03 13:05:48 +01006648
6649 dpo_reset(&dpo_44);
6650
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006651 /*
6652 * we are holding a lock on the non-eos LB of the via-entry.
6653 * do a PIC-core failover by shutting the link of the via-entry.
6654 *
6655 * shut down the link with the valid label
6656 */
6657 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006658 tm->hw[0]->sw_if_index,
6659 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006660
6661 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006662 FIB_TEST(!fib_test_validate_entry(fei,
6663 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6664 2,
6665 &a_o_10_10_11_1,
6666 &adj_o_10_10_11_2),
6667 "1.1.1.1/32 LB 2 buckets via: "
6668 "adj over 10.10.11.1, ",
6669 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006670
6671 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006672 &pfx_24001_eos);
6673 FIB_TEST(!fib_test_validate_entry(fei,
6674 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6675 2,
6676 &disp_o_10_10_11_1,
6677 &disp_o_10_10_11_2),
6678 "24001/eos LB 2 buckets via: "
6679 "mpls-disp adj over 10.10.11.1, ",
6680 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006681
6682 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006683 &pfx_24001_neos);
6684 FIB_TEST(!fib_test_validate_entry(fei,
6685 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6686 1,
6687 &a_mpls_o_10_10_11_1),
6688 "24001/neos LB 1 buckets via: "
6689 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006690
6691 /*
6692 * test that the pre-failover load-balance has been in-place
6693 * modified
6694 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006695 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006696 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006697 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6698 &current);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006699
6700 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6701 &current),
Neale Ranns2303cb12018-02-21 04:57:17 -08006702 "PIC-core LB inplace modified %U %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006703 format_dpo_id, &non_eos_1_1_1_1, 0,
6704 format_dpo_id, &current, 0);
6705
6706 dpo_reset(&non_eos_1_1_1_1);
6707 dpo_reset(&current);
6708
6709 /*
6710 * no-shut the link with the valid label
6711 */
6712 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006713 tm->hw[0]->sw_if_index,
6714 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006715
6716 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006717 FIB_TEST(!fib_test_validate_entry(fei,
6718 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6719 16, // 3 choices spread over 16 buckets
6720 &l99_eos_o_10_10_10_1,
6721 &l99_eos_o_10_10_10_1,
6722 &l99_eos_o_10_10_10_1,
6723 &l99_eos_o_10_10_10_1,
6724 &l99_eos_o_10_10_10_1,
6725 &l99_eos_o_10_10_10_1,
6726 &a_o_10_10_11_1,
6727 &a_o_10_10_11_1,
6728 &a_o_10_10_11_1,
6729 &a_o_10_10_11_1,
6730 &a_o_10_10_11_1,
6731 &adj_o_10_10_11_2,
6732 &adj_o_10_10_11_2,
6733 &adj_o_10_10_11_2,
6734 &adj_o_10_10_11_2,
6735 &adj_o_10_10_11_2),
6736 "1.1.1.1/32 LB 16 buckets via: "
6737 "label 99 over 10.10.10.1, "
6738 "adj over 10.10.11.1",
6739 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006740
6741
6742 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006743 &pfx_24001_eos);
6744 FIB_TEST(!fib_test_validate_entry(fei,
6745 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6746 16, // 3 choices spread over 16 buckets
6747 &l99_eos_o_10_10_10_1,
6748 &l99_eos_o_10_10_10_1,
6749 &l99_eos_o_10_10_10_1,
6750 &l99_eos_o_10_10_10_1,
6751 &l99_eos_o_10_10_10_1,
6752 &l99_eos_o_10_10_10_1,
6753 &disp_o_10_10_11_1,
6754 &disp_o_10_10_11_1,
6755 &disp_o_10_10_11_1,
6756 &disp_o_10_10_11_1,
6757 &disp_o_10_10_11_1,
6758 &disp_o_10_10_11_2,
6759 &disp_o_10_10_11_2,
6760 &disp_o_10_10_11_2,
6761 &disp_o_10_10_11_2,
6762 &disp_o_10_10_11_2),
6763 "24001/eos LB 16 buckets via: "
6764 "label 99 over 10.10.10.1, "
6765 "MPLS disp adj over 10.10.11.1",
6766 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006767
6768 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006769 &pfx_24001_neos);
6770 FIB_TEST(!fib_test_validate_entry(fei,
6771 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6772 2,
6773 &l99_neos_o_10_10_10_1,
6774 &a_mpls_o_10_10_11_1),
6775 "24001/neos LB 2 buckets via: "
6776 "label 99 over 10.10.10.1, "
6777 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006778
6779 /*
6780 * remove the first path with the valid label
6781 */
6782 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006783 &pfx_1_1_1_1_s_32,
6784 FIB_SOURCE_API,
6785 DPO_PROTO_IP4,
6786 &nh_10_10_10_1,
6787 tm->hw[0]->sw_if_index,
6788 ~0, // invalid fib index
6789 1,
6790 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006791
6792 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006793 FIB_TEST(!fib_test_validate_entry(fei,
6794 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6795 2,
6796 &a_o_10_10_11_1,
6797 &adj_o_10_10_11_2),
6798 "1.1.1.1/32 LB 2 buckets via: "
6799 "adj over 10.10.11.1, "
6800 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006801
6802 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006803 &pfx_24001_eos);
6804 FIB_TEST(!fib_test_validate_entry(fei,
6805 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6806 2,
6807 &disp_o_10_10_11_1,
6808 &disp_o_10_10_11_2),
6809 "24001/eos LB 2 buckets via: "
6810 "MPLS disp adj over 10.10.11.1, "
6811 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006812
6813 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006814 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006815
Neale Ranns2303cb12018-02-21 04:57:17 -08006816 FIB_TEST(!fib_test_validate_entry(fei,
6817 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6818 1,
6819 &a_mpls_o_10_10_11_1),
6820 "24001/neos LB 1 buckets via: "
6821 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006822
6823 /*
6824 * remove the other path with a valid label
6825 */
6826 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006827 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006828 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006829 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006830 .type = FT_LB_DROP,
6831 .special = {
6832 .adj = DPO_PROTO_MPLS,
6833 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07006834 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006835
6836 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006837 &pfx_1_1_1_1_s_32,
6838 FIB_SOURCE_API,
6839 DPO_PROTO_IP4,
6840 &nh_10_10_11_1,
6841 tm->hw[1]->sw_if_index,
6842 ~0, // invalid fib index
6843 1,
6844 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006845
6846 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006847 FIB_TEST(!fib_test_validate_entry(fei,
6848 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6849 1,
6850 &adj_o_10_10_11_2),
6851 "1.1.1.1/32 LB 1 buckets via: "
6852 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006853
6854 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006855 &pfx_24001_eos);
6856 FIB_TEST(!fib_test_validate_entry(fei,
6857 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6858 1,
6859 &disp_o_10_10_11_2),
6860 "24001/eos LB 1 buckets via: "
6861 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006862
6863 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006864 &pfx_24001_neos);
6865 FIB_TEST(!fib_test_validate_entry(fei,
6866 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6867 1,
6868 &mpls_bucket_drop),
6869 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006870
6871 /*
6872 * add back the path with the valid label
6873 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006874 l99 = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08006875 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006876
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006877 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006878 &pfx_1_1_1_1_s_32,
6879 FIB_SOURCE_API,
6880 FIB_ENTRY_FLAG_NONE,
6881 DPO_PROTO_IP4,
6882 &nh_10_10_10_1,
6883 tm->hw[0]->sw_if_index,
6884 ~0, // invalid fib index
6885 1,
6886 l99,
6887 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006888
6889 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006890 FIB_TEST(!fib_test_validate_entry(fei,
6891 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6892 2,
6893 &l99_eos_o_10_10_10_1,
6894 &adj_o_10_10_11_2),
6895 "1.1.1.1/32 LB 2 buckets via: "
6896 "label 99 over 10.10.10.1, "
6897 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006898
6899 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006900 &pfx_24001_eos);
6901 FIB_TEST(!fib_test_validate_entry(fei,
6902 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6903 2,
6904 &l99_eos_o_10_10_10_1,
6905 &disp_o_10_10_11_2),
6906 "24001/eos LB 2 buckets via: "
6907 "label 99 over 10.10.10.1, "
6908 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006909
6910 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006911 &pfx_24001_neos);
6912 FIB_TEST(!fib_test_validate_entry(fei,
6913 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6914 1,
6915 &l99_neos_o_10_10_10_1),
6916 "24001/neos LB 1 buckets via: "
6917 "label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006918
6919 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006920 * change the local label
6921 */
6922 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006923 &pfx_1_1_1_1_s_32,
6924 25005);
Neale Ranns1357f3b2016-10-16 12:01:42 -07006925
6926 fib_prefix_t pfx_25005_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006927 .fp_proto = FIB_PROTOCOL_MPLS,
6928 .fp_label = 25005,
6929 .fp_eos = MPLS_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006930 };
6931 fib_prefix_t pfx_25005_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006932 .fp_proto = FIB_PROTOCOL_MPLS,
6933 .fp_label = 25005,
6934 .fp_eos = MPLS_NON_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006935 };
6936
6937 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006938 fib_table_lookup(fib_index, &pfx_24001_eos)),
6939 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006940 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006941 fib_table_lookup(fib_index, &pfx_24001_neos)),
6942 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006943
6944 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006945 &pfx_25005_eos);
6946 FIB_TEST(!fib_test_validate_entry(fei,
6947 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6948 2,
6949 &l99_eos_o_10_10_10_1,
6950 &disp_o_10_10_11_2),
6951 "25005/eos LB 2 buckets via: "
6952 "label 99 over 10.10.10.1, "
6953 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006954
6955 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006956 &pfx_25005_neos);
6957 FIB_TEST(!fib_test_validate_entry(fei,
6958 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6959 1,
6960 &l99_neos_o_10_10_10_1),
6961 "25005/neos LB 1 buckets via: "
6962 "label 99 over 10.10.10.1");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006963
6964 /*
6965 * remove the local label.
6966 * the check that the MPLS entries are gone is done by the fact the
6967 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006968 */
6969 fib_table_entry_local_label_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006970 &pfx_1_1_1_1_s_32,
6971 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006972
6973 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006974 FIB_TEST(!fib_test_validate_entry(fei,
6975 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6976 2,
6977 &l99_eos_o_10_10_10_1,
6978 &adj_o_10_10_11_2),
6979 "24001/eos LB 2 buckets via: "
6980 "label 99 over 10.10.10.1, "
6981 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006982
6983 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006984 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6985 "No more MPLS FIB entries => table removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006986
6987 /*
6988 * add another via-entry for the recursive
6989 */
6990 fib_prefix_t pfx_1_1_1_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006991 .fp_len = 32,
6992 .fp_proto = FIB_PROTOCOL_IP4,
6993 .fp_addr = {
6994 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6995 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006996 };
6997 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006998 .type = FT_LB_LABEL_O_ADJ,
6999 .label_o_adj = {
7000 .adj = ai_mpls_10_10_10_1,
7001 .label = 101,
7002 .eos = MPLS_EOS,
7003 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007004 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007005 fib_mpls_label_t *l101 = NULL, fml101 = {
7006 .fml_value = 101,
7007 };
7008 vec_add1(l101, fml101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007009
7010 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007011 &pfx_1_1_1_2_s_32,
7012 FIB_SOURCE_API,
7013 FIB_ENTRY_FLAG_NONE,
7014 DPO_PROTO_IP4,
7015 &nh_10_10_10_1,
7016 tm->hw[0]->sw_if_index,
7017 ~0, // invalid fib index
7018 1,
7019 l101,
7020 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007021
Neale Ranns2303cb12018-02-21 04:57:17 -08007022 FIB_TEST(!fib_test_validate_entry(fei,
7023 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7024 1,
7025 &l101_eos_o_10_10_10_1),
7026 "1.1.1.2/32 LB 1 buckets via: "
7027 "label 101 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007028
Neale Ranns948e00f2016-10-20 13:39:34 +01007029 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007030 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007031 &pfx_1_1_1_1_s_32),
7032 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7033 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007034 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007035 &pfx_1_1_1_2_s_32),
7036 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7037 &non_eos_1_1_1_2);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007038
7039 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007040 .type = FT_LB_LABEL_O_LB,
7041 .label_o_lb = {
7042 .lb = non_eos_1_1_1_2.dpoi_index,
7043 .label = 1601,
7044 .eos = MPLS_EOS,
7045 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007046 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007047 fib_mpls_label_t *l1601 = NULL, fml1601 = {
7048 .fml_value = 1601,
7049 };
7050 vec_add1(l1601, fml1601);
Neale Rannsad422ed2016-11-02 14:20:04 +00007051
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007052 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
7053
7054 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007055 &pfx_2_2_2_2_s_32,
7056 FIB_SOURCE_API,
7057 FIB_ENTRY_FLAG_NONE,
7058 DPO_PROTO_IP4,
7059 &pfx_1_1_1_2_s_32.fp_addr,
7060 ~0,
7061 fib_index,
7062 1,
7063 l1601,
7064 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007065
Neale Ranns2303cb12018-02-21 04:57:17 -08007066 FIB_TEST(!fib_test_validate_entry(fei,
7067 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7068 2,
7069 &l1600_eos_o_1_1_1_1,
7070 &l1601_eos_o_1_1_1_2),
7071 "2.2.2.2/32 LB 2 buckets via: "
7072 "label 1600 via 1.1,1.1, "
7073 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007074
7075 /*
7076 * update the via-entry so it no longer has an imp-null path.
7077 * the LB for the recursive can use an imp-null
7078 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007079 l_imp_null = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007080 vec_add1(l_imp_null, fml_imp_null);
Neale Rannsad422ed2016-11-02 14:20:04 +00007081
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007082 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007083 &pfx_1_1_1_2_s_32,
7084 FIB_SOURCE_API,
7085 FIB_ENTRY_FLAG_NONE,
7086 DPO_PROTO_IP4,
7087 &nh_10_10_11_1,
7088 tm->hw[1]->sw_if_index,
7089 ~0, // invalid fib index
7090 1,
7091 l_imp_null,
7092 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007093
Neale Ranns2303cb12018-02-21 04:57:17 -08007094 FIB_TEST(!fib_test_validate_entry(fei,
7095 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7096 1,
7097 &a_o_10_10_11_1),
7098 "1.1.1.2/32 LB 1 buckets via: "
7099 "adj 10.10.11.1");
7100
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007101 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007102 FIB_TEST(!fib_test_validate_entry(fei,
7103 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7104 2,
7105 &l1600_eos_o_1_1_1_1,
7106 &l1601_eos_o_1_1_1_2),
7107 "2.2.2.2/32 LB 2 buckets via: "
7108 "label 1600 via 1.1,1.1, "
7109 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007110
7111 /*
7112 * update the via-entry so it no longer has labelled paths.
7113 * the LB for the recursive should exclue this via form its LB
7114 */
7115 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007116 &pfx_1_1_1_2_s_32,
7117 FIB_SOURCE_API,
7118 FIB_ENTRY_FLAG_NONE,
7119 DPO_PROTO_IP4,
7120 &nh_10_10_11_1,
7121 tm->hw[1]->sw_if_index,
7122 ~0, // invalid fib index
7123 1,
7124 NULL,
7125 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007126
Neale Ranns2303cb12018-02-21 04:57:17 -08007127 FIB_TEST(!fib_test_validate_entry(fei,
7128 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7129 1,
7130 &a_o_10_10_11_1),
7131 "1.1.1.2/32 LB 1 buckets via: "
7132 "adj 10.10.11.1");
7133
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007134 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007135 FIB_TEST(!fib_test_validate_entry(fei,
7136 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7137 1,
7138 &l1600_eos_o_1_1_1_1),
7139 "2.2.2.2/32 LB 1 buckets via: "
7140 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007141
7142 dpo_reset(&non_eos_1_1_1_1);
7143 dpo_reset(&non_eos_1_1_1_2);
7144
7145 /*
7146 * Add a recursive with no out-labels. We expect to use the IP of the via
7147 */
7148 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007149 .fp_len = 32,
7150 .fp_proto = FIB_PROTOCOL_IP4,
7151 .fp_addr = {
7152 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7153 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007154 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007155 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007156
7157 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007158 &pfx_2_2_2_3_s_32,
7159 FIB_SOURCE_API,
7160 FIB_ENTRY_FLAG_NONE,
7161 DPO_PROTO_IP4,
7162 &pfx_1_1_1_1_s_32.fp_addr,
7163 ~0,
7164 fib_index,
7165 1,
7166 NULL,
7167 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007168
7169 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007170 &pfx_1_1_1_1_s_32),
7171 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7172 &ip_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007173
7174 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007175 .type = FT_LB_O_LB,
7176 .lb = {
7177 .lb = ip_1_1_1_1.dpoi_index,
7178 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007179 };
7180
7181 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007182 FIB_TEST(!fib_test_validate_entry(fei,
7183 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7184 1,
7185 &ip_o_1_1_1_1),
7186 "2.2.2.2.3/32 LB 1 buckets via: "
7187 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007188
7189 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08007190 * Add a recursive with an imp-null out-label.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007191 * We expect to use the IP of the via
7192 */
7193 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007194 .fp_len = 32,
7195 .fp_proto = FIB_PROTOCOL_IP4,
7196 .fp_addr = {
7197 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7198 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007199 };
7200
7201 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007202 &pfx_2_2_2_4_s_32,
7203 FIB_SOURCE_API,
7204 FIB_ENTRY_FLAG_NONE,
7205 DPO_PROTO_IP4,
7206 &pfx_1_1_1_1_s_32.fp_addr,
7207 ~0,
7208 fib_index,
7209 1,
7210 NULL,
7211 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007212
7213 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007214 FIB_TEST(!fib_test_validate_entry(fei,
7215 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7216 1,
7217 &ip_o_1_1_1_1),
7218 "2.2.2.2.4/32 LB 1 buckets via: "
7219 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007220
7221 dpo_reset(&ip_1_1_1_1);
7222
7223 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007224 * Create an entry with a deep label stack
7225 */
7226 fib_prefix_t pfx_2_2_5_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007227 .fp_len = 32,
7228 .fp_proto = FIB_PROTOCOL_IP4,
7229 .fp_addr = {
7230 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7231 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007232 };
7233 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007234 .type = FT_LB_LABEL_STACK_O_ADJ,
7235 .label_stack_o_adj = {
7236 .adj = ai_mpls_10_10_11_1,
7237 .label_stack_size = 8,
7238 .label_stack = {
7239 200, 201, 202, 203, 204, 205, 206, 207
7240 },
7241 .eos = MPLS_EOS,
7242 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007243 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007244 fib_mpls_label_t *label_stack = NULL;
Neale Rannsad422ed2016-11-02 14:20:04 +00007245 vec_validate(label_stack, 7);
7246 for (ii = 0; ii < 8; ii++)
7247 {
Neale Ranns31ed7442018-02-23 05:29:09 -08007248 label_stack[ii].fml_value = ii + 200;
Neale Rannsad422ed2016-11-02 14:20:04 +00007249 }
7250
7251 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007252 &pfx_2_2_5_5_s_32,
7253 FIB_SOURCE_API,
7254 FIB_ENTRY_FLAG_NONE,
7255 DPO_PROTO_IP4,
7256 &nh_10_10_11_1,
7257 tm->hw[1]->sw_if_index,
7258 ~0, // invalid fib index
7259 1,
7260 label_stack,
7261 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00007262
Neale Ranns2303cb12018-02-21 04:57:17 -08007263 FIB_TEST(!fib_test_validate_entry(fei,
7264 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7265 1,
7266 &ls_eos_o_10_10_10_1),
7267 "2.2.5.5/32 LB 1 buckets via: "
7268 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00007269 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7270
7271 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007272 * cleanup
7273 */
7274 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007275 &pfx_1_1_1_2_s_32,
7276 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007277
7278 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007279 FIB_TEST(!fib_test_validate_entry(fei,
7280 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7281 1,
7282 &l1600_eos_o_1_1_1_1),
7283 "2.2.2.2/32 LB 1 buckets via: "
7284 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007285
7286 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007287 &pfx_1_1_1_1_s_32,
7288 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007289
Neale Ranns2303cb12018-02-21 04:57:17 -08007290 FIB_TEST(!fib_test_validate_entry(fei,
7291 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7292 1,
7293 &bucket_drop),
7294 "2.2.2.2/32 LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007295
7296 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007297 &pfx_2_2_2_2_s_32,
7298 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007299 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007300 &pfx_2_2_2_3_s_32,
7301 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007302 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007303 &pfx_2_2_2_4_s_32,
7304 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007305
7306 adj_unlock(ai_mpls_10_10_10_1);
7307 adj_unlock(ai_mpls_10_10_11_2);
7308 adj_unlock(ai_v4_10_10_11_1);
7309 adj_unlock(ai_v4_10_10_11_2);
7310 adj_unlock(ai_mpls_10_10_11_1);
7311
7312 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08007313 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007314
7315 local0_pfx.fp_len = 32;
7316 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007317 &local0_pfx,
7318 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007319 local0_pfx.fp_len = 24;
7320 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007321 &local0_pfx,
7322 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007323 local1_pfx.fp_len = 32;
7324 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007325 &local1_pfx,
7326 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007327 local1_pfx.fp_len = 24;
7328 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007329 &local1_pfx,
7330 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007331
7332 /*
7333 * +1 for the drop LB in the MPLS tables.
7334 */
7335 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08007336 "Load-balance resources freed %d of %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007337 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007338
Neale Ranns2303cb12018-02-21 04:57:17 -08007339 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007340}
7341
7342#define N_TEST_CHILDREN 4
7343#define PARENT_INDEX 0
7344
7345typedef struct fib_node_test_t_
7346{
7347 fib_node_t node;
7348 u32 sibling;
7349 u32 index;
7350 fib_node_back_walk_ctx_t *ctxs;
7351 u32 destroyed;
7352} fib_node_test_t;
7353
7354static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7355
7356#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7357
Neale Ranns2303cb12018-02-21 04:57:17 -08007358#define FOR_EACH_TEST_CHILD(_tc) \
7359 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7360 ii < N_TEST_CHILDREN+1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007361 ii++, (_tc) = &fib_test_nodes[ii])
7362
7363static fib_node_t *
7364fib_test_child_get_node (fib_node_index_t index)
7365{
7366 return (&fib_test_nodes[index].node);
7367}
7368
7369static int fib_test_walk_spawns_walks;
7370
7371static fib_node_back_walk_rc_t
7372fib_test_child_back_walk_notify (fib_node_t *node,
7373 fib_node_back_walk_ctx_t *ctx)
7374{
7375 fib_node_test_t *tc = (fib_node_test_t*) node;
7376
7377 vec_add1(tc->ctxs, *ctx);
7378
7379 if (1 == fib_test_walk_spawns_walks)
7380 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7381 if (2 == fib_test_walk_spawns_walks)
7382 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7383 FIB_WALK_PRIORITY_HIGH, ctx);
7384
7385 return (FIB_NODE_BACK_WALK_CONTINUE);
7386}
7387
7388static void
7389fib_test_child_last_lock_gone (fib_node_t *node)
7390{
7391 fib_node_test_t *tc = (fib_node_test_t *)node;
7392
7393 tc->destroyed = 1;
7394}
7395
7396/**
7397 * The FIB walk's graph node virtual function table
7398 */
7399static const fib_node_vft_t fib_test_child_vft = {
7400 .fnv_get = fib_test_child_get_node,
7401 .fnv_last_lock = fib_test_child_last_lock_gone,
7402 .fnv_back_walk = fib_test_child_back_walk_notify,
7403};
7404
7405/*
7406 * the function (that should have been static but isn't so I can do this)
7407 * that processes the walk from the async queue,
7408 */
7409f64 fib_walk_process_queues(vlib_main_t * vm,
7410 const f64 quota);
7411u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7412
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007413static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007414fib_test_walk (void)
7415{
7416 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7417 fib_node_test_t *tc;
7418 vlib_main_t *vm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007419 u32 ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007420
Neale Ranns2303cb12018-02-21 04:57:17 -08007421 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007422 vm = vlib_get_main();
7423 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7424
7425 /*
7426 * init a fake node on which we will add children
7427 */
7428 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7429 FIB_NODE_TYPE_TEST);
7430
7431 FOR_EACH_TEST_CHILD(tc)
7432 {
7433 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7434 fib_node_lock(&tc->node);
7435 tc->ctxs = NULL;
7436 tc->index = ii;
7437 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7438 PARENT_INDEX,
7439 FIB_NODE_TYPE_TEST, ii);
7440 }
7441
7442 /*
7443 * enqueue a walk across the parents children.
7444 */
Neale Ranns450cd302016-11-09 17:49:42 +00007445 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007446
7447 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7448 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7449 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7450 "Parent has %d children pre-walk",
7451 fib_node_list_get_size(PARENT()->fn_children));
7452
7453 /*
7454 * give the walk a large amount of time so it gets to the end
7455 */
7456 fib_walk_process_queues(vm, 1);
7457
7458 FOR_EACH_TEST_CHILD(tc)
7459 {
7460 FIB_TEST(1 == vec_len(tc->ctxs),
7461 "%d child visitsed %d times",
7462 ii, vec_len(tc->ctxs));
7463 vec_free(tc->ctxs);
7464 }
7465 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7466 "Queue is empty post walk");
7467 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7468 "Parent has %d children post walk",
7469 fib_node_list_get_size(PARENT()->fn_children));
7470
7471 /*
7472 * walk again. should be no increase in the number of visits, since
7473 * the walk will have terminated.
7474 */
7475 fib_walk_process_queues(vm, 1);
7476
7477 FOR_EACH_TEST_CHILD(tc)
7478 {
7479 FIB_TEST(0 == vec_len(tc->ctxs),
7480 "%d child visitsed %d times",
7481 ii, vec_len(tc->ctxs));
7482 }
7483
7484 /*
7485 * schedule a low and hig priority walk. expect the high to be performed
7486 * before the low.
7487 * schedule the high prio walk first so that it is further from the head
7488 * of the dependency list. that way it won't merge with the low one.
7489 */
7490 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7491 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7492
7493 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7494 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7495 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7496 FIB_WALK_PRIORITY_LOW, &low_ctx);
7497
7498 fib_walk_process_queues(vm, 1);
7499
7500 FOR_EACH_TEST_CHILD(tc)
7501 {
7502 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7503 "%d child visitsed by high prio walk", ii);
7504 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7505 "%d child visitsed by low prio walk", ii);
7506 vec_free(tc->ctxs);
7507 }
7508 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7509 "Queue is empty post prio walk");
7510 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7511 "Parent has %d children post prio walk",
7512 fib_node_list_get_size(PARENT()->fn_children));
7513
7514 /*
7515 * schedule 2 walks of the same priority that can be megred.
7516 * expect that each child is thus visited only once.
7517 */
7518 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7519 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7520
7521 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7522 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7523 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7524 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7525
7526 fib_walk_process_queues(vm, 1);
7527
7528 FOR_EACH_TEST_CHILD(tc)
7529 {
7530 FIB_TEST(1 == vec_len(tc->ctxs),
7531 "%d child visitsed %d times during merge walk",
7532 ii, vec_len(tc->ctxs));
7533 vec_free(tc->ctxs);
7534 }
7535 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7536 "Queue is empty post merge walk");
7537 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7538 "Parent has %d children post merge walk",
7539 fib_node_list_get_size(PARENT()->fn_children));
7540
7541 /*
7542 * schedule 2 walks of the same priority that cannot be megred.
7543 * expect that each child is thus visited twice and in the order
7544 * in which the walks were scheduled.
7545 */
7546 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7547 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7548
7549 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7550 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7551 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7552 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7553
7554 fib_walk_process_queues(vm, 1);
7555
7556 FOR_EACH_TEST_CHILD(tc)
7557 {
7558 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7559 "%d child visitsed by high prio walk", ii);
7560 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7561 "%d child visitsed by low prio walk", ii);
7562 vec_free(tc->ctxs);
7563 }
7564 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7565 "Queue is empty post no-merge walk");
7566 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7567 "Parent has %d children post no-merge walk",
7568 fib_node_list_get_size(PARENT()->fn_children));
7569
7570 /*
7571 * schedule a walk that makes one one child progress.
7572 * we do this by giving the queue draining process zero
7573 * time quanta. it's a do..while loop, so it does something.
7574 */
Neale Ranns450cd302016-11-09 17:49:42 +00007575 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007576
7577 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7578 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7579 fib_walk_process_queues(vm, 0);
7580
7581 FOR_EACH_TEST_CHILD(tc)
7582 {
7583 if (ii == N_TEST_CHILDREN)
7584 {
7585 FIB_TEST(1 == vec_len(tc->ctxs),
7586 "%d child visitsed %d times in zero quanta walk",
7587 ii, vec_len(tc->ctxs));
7588 }
7589 else
7590 {
7591 FIB_TEST(0 == vec_len(tc->ctxs),
7592 "%d child visitsed %d times in 0 quanta walk",
7593 ii, vec_len(tc->ctxs));
7594 }
7595 }
7596 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7597 "Queue is not empty post zero quanta walk");
7598 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7599 "Parent has %d children post zero qunta walk",
7600 fib_node_list_get_size(PARENT()->fn_children));
7601
7602 /*
7603 * another one step
7604 */
7605 fib_walk_process_queues(vm, 0);
7606
7607 FOR_EACH_TEST_CHILD(tc)
7608 {
7609 if (ii >= N_TEST_CHILDREN-1)
7610 {
7611 FIB_TEST(1 == vec_len(tc->ctxs),
7612 "%d child visitsed %d times in 2nd zero quanta walk",
7613 ii, vec_len(tc->ctxs));
7614 }
7615 else
7616 {
7617 FIB_TEST(0 == vec_len(tc->ctxs),
7618 "%d child visitsed %d times in 2nd 0 quanta walk",
7619 ii, vec_len(tc->ctxs));
7620 }
7621 }
7622 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7623 "Queue is not empty post zero quanta walk");
7624 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7625 "Parent has %d children post zero qunta walk",
7626 fib_node_list_get_size(PARENT()->fn_children));
7627
7628 /*
7629 * schedule another walk that will catch-up and merge.
7630 */
7631 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7632 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7633 fib_walk_process_queues(vm, 1);
7634
7635 FOR_EACH_TEST_CHILD(tc)
7636 {
7637 if (ii >= N_TEST_CHILDREN-1)
7638 {
7639 FIB_TEST(2 == vec_len(tc->ctxs),
7640 "%d child visitsed %d times in 2nd zero quanta merge walk",
7641 ii, vec_len(tc->ctxs));
7642 vec_free(tc->ctxs);
7643 }
7644 else
7645 {
7646 FIB_TEST(1 == vec_len(tc->ctxs),
7647 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7648 ii, vec_len(tc->ctxs));
7649 vec_free(tc->ctxs);
7650 }
7651 }
7652 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7653 "Queue is not empty post 2nd zero quanta merge walk");
7654 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7655 "Parent has %d children post 2nd zero qunta merge walk",
7656 fib_node_list_get_size(PARENT()->fn_children));
7657
7658 /*
7659 * park a async walk in the middle of the list, then have an sync walk catch
7660 * it. same expectations as async catches async.
7661 */
Neale Ranns450cd302016-11-09 17:49:42 +00007662 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007663
7664 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7665 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7666
7667 fib_walk_process_queues(vm, 0);
7668 fib_walk_process_queues(vm, 0);
7669
7670 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7671
7672 FOR_EACH_TEST_CHILD(tc)
7673 {
7674 if (ii >= N_TEST_CHILDREN-1)
7675 {
7676 FIB_TEST(2 == vec_len(tc->ctxs),
7677 "%d child visitsed %d times in sync catches async walk",
7678 ii, vec_len(tc->ctxs));
7679 vec_free(tc->ctxs);
7680 }
7681 else
7682 {
7683 FIB_TEST(1 == vec_len(tc->ctxs),
7684 "%d child visitsed %d times in sync catches async walk",
7685 ii, vec_len(tc->ctxs));
7686 vec_free(tc->ctxs);
7687 }
7688 }
7689 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7690 "Queue is not empty post 2nd zero quanta merge walk");
7691 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7692 "Parent has %d children post 2nd zero qunta merge walk",
7693 fib_node_list_get_size(PARENT()->fn_children));
7694
7695 /*
7696 * make the parent a child of one of its children, thus inducing a routing loop.
7697 */
7698 fib_test_nodes[PARENT_INDEX].sibling =
7699 fib_node_child_add(FIB_NODE_TYPE_TEST,
7700 1, // the first child
7701 FIB_NODE_TYPE_TEST,
7702 PARENT_INDEX);
7703
7704 /*
7705 * execute a sync walk from the parent. each child visited spawns more sync
7706 * walks. we expect the walk to terminate.
7707 */
7708 fib_test_walk_spawns_walks = 1;
7709
7710 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7711
7712 FOR_EACH_TEST_CHILD(tc)
7713 {
7714 /*
7715 * child 1 - which is last in the list - has the loop.
7716 * the other children a re thus visitsed first. the we meet
7717 * child 1. we go round the loop again, visting the other children.
7718 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7719 * again.
7720 */
7721 if (1 == ii)
7722 {
7723 FIB_TEST(1 == vec_len(tc->ctxs),
7724 "child %d visitsed %d times during looped sync walk",
7725 ii, vec_len(tc->ctxs));
7726 }
7727 else
7728 {
7729 FIB_TEST(2 == vec_len(tc->ctxs),
7730 "child %d visitsed %d times during looped sync walk",
7731 ii, vec_len(tc->ctxs));
7732 }
7733 vec_free(tc->ctxs);
7734 }
7735 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7736 "Parent has %d children post sync loop walk",
7737 fib_node_list_get_size(PARENT()->fn_children));
7738
7739 /*
7740 * the walk doesn't reach the max depth because the infra knows that sync
7741 * meets sync implies a loop and bails early.
7742 */
7743 FIB_TEST(high_ctx.fnbw_depth == 9,
7744 "Walk context depth %d post sync loop walk",
7745 high_ctx.fnbw_depth);
7746
7747 /*
7748 * execute an async walk of the graph loop, with each child spawns sync walks
7749 */
7750 high_ctx.fnbw_depth = 0;
7751 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7752 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7753
7754 fib_walk_process_queues(vm, 1);
7755
7756 FOR_EACH_TEST_CHILD(tc)
7757 {
7758 /*
7759 * we don't really care how many times the children are visisted, as long as
7760 * it is more than once.
7761 */
7762 FIB_TEST(1 <= vec_len(tc->ctxs),
7763 "child %d visitsed %d times during looped aync spawns sync walk",
7764 ii, vec_len(tc->ctxs));
7765 vec_free(tc->ctxs);
7766 }
7767
7768 /*
7769 * execute an async walk of the graph loop, with each child spawns async walks
7770 */
7771 fib_test_walk_spawns_walks = 2;
7772 high_ctx.fnbw_depth = 0;
7773 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7774 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7775
7776 fib_walk_process_queues(vm, 1);
7777
7778 FOR_EACH_TEST_CHILD(tc)
7779 {
7780 /*
7781 * we don't really care how many times the children are visisted, as long as
7782 * it is more than once.
7783 */
7784 FIB_TEST(1 <= vec_len(tc->ctxs),
7785 "child %d visitsed %d times during looped async spawns async walk",
7786 ii, vec_len(tc->ctxs));
Neale Ranns2303cb12018-02-21 04:57:17 -08007787 vec_free(tc->ctxs);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007788 }
7789
7790
7791 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7792 1, // the first child
7793 fib_test_nodes[PARENT_INDEX].sibling);
7794
7795 /*
7796 * cleanup
7797 */
7798 FOR_EACH_TEST_CHILD(tc)
7799 {
7800 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7801 tc->sibling);
7802 fib_node_deinit(&tc->node);
7803 fib_node_unlock(&tc->node);
7804 }
7805 fib_node_deinit(PARENT());
7806
7807 /*
7808 * The parent will be destroyed when the last lock on it goes.
7809 * this test ensures all the walk objects are unlocking it.
7810 */
7811 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7812 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007813
Neale Ranns2303cb12018-02-21 04:57:17 -08007814 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007815}
7816
Neale Ranns88fc83e2017-04-05 08:11:14 -07007817/*
7818 * declaration of the otherwise static callback functions
7819 */
7820void fib_bfd_notify (bfd_listen_event_e event,
7821 const bfd_session_t *session);
7822void adj_bfd_notify (bfd_listen_event_e event,
7823 const bfd_session_t *session);
7824
7825/**
7826 * Test BFD session interaction with FIB
7827 */
7828static int
7829fib_test_bfd (void)
7830{
7831 fib_node_index_t fei;
7832 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007833 int n_feis, res;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007834
Neale Ranns2303cb12018-02-21 04:57:17 -08007835 res = 0;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007836 /* via 10.10.10.1 */
7837 ip46_address_t nh_10_10_10_1 = {
7838 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7839 };
7840 /* via 10.10.10.2 */
7841 ip46_address_t nh_10_10_10_2 = {
7842 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7843 };
7844 /* via 10.10.10.10 */
7845 ip46_address_t nh_10_10_10_10 = {
7846 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7847 };
7848 n_feis = fib_entry_pool_size();
7849
7850 tm = &test_main;
7851
7852 /*
7853 * add interface routes. we'll assume this works. it's tested elsewhere
7854 */
7855 fib_prefix_t pfx_10_10_10_10_s_24 = {
7856 .fp_len = 24,
7857 .fp_proto = FIB_PROTOCOL_IP4,
7858 .fp_addr = nh_10_10_10_10,
7859 };
7860
7861 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7862 FIB_SOURCE_INTERFACE,
7863 (FIB_ENTRY_FLAG_CONNECTED |
7864 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007865 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007866 NULL,
7867 tm->hw[0]->sw_if_index,
7868 ~0, // invalid fib index
7869 1, // weight
7870 NULL,
7871 FIB_ROUTE_PATH_FLAG_NONE);
7872
7873 fib_prefix_t pfx_10_10_10_10_s_32 = {
7874 .fp_len = 32,
7875 .fp_proto = FIB_PROTOCOL_IP4,
7876 .fp_addr = nh_10_10_10_10,
7877 };
7878 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7879 FIB_SOURCE_INTERFACE,
7880 (FIB_ENTRY_FLAG_CONNECTED |
7881 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007882 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007883 NULL,
7884 tm->hw[0]->sw_if_index,
7885 ~0, // invalid fib index
7886 1, // weight
7887 NULL,
7888 FIB_ROUTE_PATH_FLAG_NONE);
7889
7890 /*
7891 * A BFD session via a neighbour we do not yet know
7892 */
7893 bfd_session_t bfd_10_10_10_1 = {
7894 .udp = {
7895 .key = {
7896 .fib_index = 0,
7897 .peer_addr = nh_10_10_10_1,
7898 },
7899 },
7900 .hop_type = BFD_HOP_TYPE_MULTI,
7901 .local_state = BFD_STATE_init,
7902 };
7903
7904 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7905
7906 /*
7907 * A new entry will be created that forwards via the adj
7908 */
7909 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7910 VNET_LINK_IP4,
7911 &nh_10_10_10_1,
7912 tm->hw[0]->sw_if_index);
7913 fib_prefix_t pfx_10_10_10_1_s_32 = {
7914 .fp_addr = nh_10_10_10_1,
7915 .fp_len = 32,
7916 .fp_proto = FIB_PROTOCOL_IP4,
7917 };
7918 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7919 .type = FT_LB_ADJ,
7920 .adj = {
7921 .adj = ai_10_10_10_1,
7922 },
7923 };
7924
7925 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007926 FIB_TEST(!fib_test_validate_entry(fei,
7927 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7928 1,
7929 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007930 "BFD sourced %U via %U",
7931 format_fib_prefix, &pfx_10_10_10_1_s_32,
7932 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7933
7934 /*
7935 * Delete the BFD session. Expect the fib_entry to be removed
7936 */
7937 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7938
7939 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7940 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7941 "BFD sourced %U removed",
7942 format_fib_prefix, &pfx_10_10_10_1_s_32);
7943
7944 /*
7945 * Add the BFD source back
7946 */
7947 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7948
7949 /*
7950 * source the entry via the ADJ fib
7951 */
Neale Ranns81424992017-05-18 03:03:22 -07007952 fei = fib_table_entry_path_add(0,
7953 &pfx_10_10_10_1_s_32,
7954 FIB_SOURCE_ADJ,
7955 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007956 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007957 &nh_10_10_10_1,
7958 tm->hw[0]->sw_if_index,
7959 ~0, // invalid fib index
7960 1,
7961 NULL,
7962 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007963
7964 /*
7965 * Delete the BFD session. Expect the fib_entry to remain
7966 */
7967 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7968
7969 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007970 FIB_TEST(!fib_test_validate_entry(fei,
7971 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7972 1,
7973 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007974 "BFD sourced %U remains via %U",
7975 format_fib_prefix, &pfx_10_10_10_1_s_32,
7976 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7977
7978 /*
7979 * Add the BFD source back
7980 */
7981 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7982
7983 /*
7984 * Create another ADJ FIB
7985 */
7986 fib_prefix_t pfx_10_10_10_2_s_32 = {
7987 .fp_addr = nh_10_10_10_2,
7988 .fp_len = 32,
7989 .fp_proto = FIB_PROTOCOL_IP4,
7990 };
Neale Ranns81424992017-05-18 03:03:22 -07007991 fib_table_entry_path_add(0,
7992 &pfx_10_10_10_2_s_32,
7993 FIB_SOURCE_ADJ,
7994 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007995 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007996 &nh_10_10_10_2,
7997 tm->hw[0]->sw_if_index,
7998 ~0, // invalid fib index
7999 1,
8000 NULL,
8001 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008002 /*
8003 * A BFD session for the new ADJ FIB
8004 */
8005 bfd_session_t bfd_10_10_10_2 = {
8006 .udp = {
8007 .key = {
8008 .fib_index = 0,
8009 .peer_addr = nh_10_10_10_2,
8010 },
8011 },
8012 .hop_type = BFD_HOP_TYPE_MULTI,
8013 .local_state = BFD_STATE_init,
8014 };
8015
8016 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
8017
8018 /*
8019 * remove the adj-fib source whilst the session is present
8020 * then add it back
8021 */
8022 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07008023 fib_table_entry_path_add(0,
8024 &pfx_10_10_10_2_s_32,
8025 FIB_SOURCE_ADJ,
8026 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07008027 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07008028 &nh_10_10_10_2,
8029 tm->hw[0]->sw_if_index,
8030 ~0, // invalid fib index
8031 1,
8032 NULL,
8033 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008034
8035 /*
8036 * Before adding a recursive via the BFD tracked ADJ-FIBs,
8037 * bring one of the sessions UP, leave the other down
8038 */
8039 bfd_10_10_10_1.local_state = BFD_STATE_up;
8040 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8041 bfd_10_10_10_2.local_state = BFD_STATE_down;
8042 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8043
8044 /*
8045 * A recursive prefix via both of the ADJ FIBs
8046 */
8047 fib_prefix_t pfx_200_0_0_0_s_24 = {
8048 .fp_proto = FIB_PROTOCOL_IP4,
8049 .fp_len = 32,
8050 .fp_addr = {
8051 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
8052 },
8053 };
8054 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
8055
8056 dpo_10_10_10_1 =
8057 fib_entry_contribute_ip_forwarding(
8058 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
8059 dpo_10_10_10_2 =
8060 fib_entry_contribute_ip_forwarding(
8061 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
8062
8063 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
8064 .type = FT_LB_O_LB,
8065 .lb = {
8066 .lb = dpo_10_10_10_1->dpoi_index,
8067 },
8068 };
8069 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8070 .type = FT_LB_O_LB,
8071 .lb = {
8072 .lb = dpo_10_10_10_2->dpoi_index,
8073 },
8074 };
8075
8076 /*
8077 * A prefix via the adj-fib that is BFD down => DROP
8078 */
8079 fei = fib_table_entry_path_add(0,
8080 &pfx_200_0_0_0_s_24,
8081 FIB_SOURCE_API,
8082 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008083 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008084 &nh_10_10_10_2,
8085 ~0, // recursive
8086 0, // default fib index
8087 1,
8088 NULL,
8089 FIB_ROUTE_PATH_FLAG_NONE);
8090 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8091 "%U resolves via drop",
8092 format_fib_prefix, &pfx_200_0_0_0_s_24);
8093
8094 /*
8095 * add a path via the UP BFD adj-fib.
8096 * we expect that the DOWN BFD ADJ FIB is not used.
8097 */
8098 fei = fib_table_entry_path_add(0,
8099 &pfx_200_0_0_0_s_24,
8100 FIB_SOURCE_API,
8101 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008102 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008103 &nh_10_10_10_1,
8104 ~0, // recursive
8105 0, // default fib index
8106 1,
8107 NULL,
8108 FIB_ROUTE_PATH_FLAG_NONE);
8109
Neale Ranns2303cb12018-02-21 04:57:17 -08008110 FIB_TEST(!fib_test_validate_entry(fei,
8111 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8112 1,
8113 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008114 "Recursive %U only UP BFD adj-fibs",
8115 format_fib_prefix, &pfx_200_0_0_0_s_24);
8116
8117 /*
8118 * Send a BFD state change to UP - both sessions are now up
8119 * the recursive prefix should LB over both
8120 */
8121 bfd_10_10_10_2.local_state = BFD_STATE_up;
8122 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8123
8124
Neale Ranns2303cb12018-02-21 04:57:17 -08008125 FIB_TEST(!fib_test_validate_entry(fei,
8126 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8127 2,
8128 &lb_o_10_10_10_1,
8129 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008130 "Recursive %U via both UP BFD adj-fibs",
8131 format_fib_prefix, &pfx_200_0_0_0_s_24);
8132
8133 /*
8134 * Send a BFD state change to DOWN
8135 * the recursive prefix should exclude the down
8136 */
8137 bfd_10_10_10_2.local_state = BFD_STATE_down;
8138 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8139
8140
Neale Ranns2303cb12018-02-21 04:57:17 -08008141 FIB_TEST(!fib_test_validate_entry(fei,
8142 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8143 1,
8144 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008145 "Recursive %U via only UP",
8146 format_fib_prefix, &pfx_200_0_0_0_s_24);
8147
8148 /*
8149 * Delete the BFD session while it is in the DOWN state.
8150 * FIB should consider the entry's state as back up
8151 */
8152 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8153
Neale Ranns2303cb12018-02-21 04:57:17 -08008154 FIB_TEST(!fib_test_validate_entry(fei,
8155 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8156 2,
8157 &lb_o_10_10_10_1,
8158 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008159 "Recursive %U via both UP BFD adj-fibs post down session delete",
8160 format_fib_prefix, &pfx_200_0_0_0_s_24);
8161
8162 /*
8163 * Delete the BFD other session while it is in the UP state.
8164 */
8165 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8166
Neale Ranns2303cb12018-02-21 04:57:17 -08008167 FIB_TEST(!fib_test_validate_entry(fei,
8168 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8169 2,
8170 &lb_o_10_10_10_1,
8171 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008172 "Recursive %U via both UP BFD adj-fibs post up session delete",
8173 format_fib_prefix, &pfx_200_0_0_0_s_24);
8174
8175 /*
8176 * cleaup
8177 */
8178 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8179 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8180 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8181
8182 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8183 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8184
8185 adj_unlock(ai_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008186 /*
Neale Ranns88fc83e2017-04-05 08:11:14 -07008187 * test no-one left behind
8188 */
8189 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8190 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8191
8192 /*
8193 * Single-hop BFD tests
8194 */
8195 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8196 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8197
8198 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8199
8200 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8201 VNET_LINK_IP4,
8202 &nh_10_10_10_1,
8203 tm->hw[0]->sw_if_index);
8204 /*
8205 * whilst the BFD session is not signalled, the adj is up
8206 */
8207 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on uninit session");
8208
8209 /*
8210 * bring the BFD session up
8211 */
8212 bfd_10_10_10_1.local_state = BFD_STATE_up;
8213 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8214 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8215
8216 /*
8217 * bring the BFD session down
8218 */
8219 bfd_10_10_10_1.local_state = BFD_STATE_down;
8220 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8221 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8222
8223
8224 /*
8225 * add an attached next hop FIB entry via the down adj
8226 */
8227 fib_prefix_t pfx_5_5_5_5_s_32 = {
8228 .fp_addr = {
8229 .ip4 = {
8230 .as_u32 = clib_host_to_net_u32(0x05050505),
8231 },
8232 },
8233 .fp_len = 32,
8234 .fp_proto = FIB_PROTOCOL_IP4,
8235 };
8236
8237 fei = fib_table_entry_path_add(0,
8238 &pfx_5_5_5_5_s_32,
8239 FIB_SOURCE_CLI,
8240 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008241 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008242 &nh_10_10_10_1,
8243 tm->hw[0]->sw_if_index,
8244 ~0, // invalid fib index
8245 1,
8246 NULL,
8247 FIB_ROUTE_PATH_FLAG_NONE);
8248 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8249 "%U resolves via drop",
8250 format_fib_prefix, &pfx_5_5_5_5_s_32);
8251
8252 /*
8253 * Add a path via an ADJ that is up
8254 */
8255 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8256 VNET_LINK_IP4,
8257 &nh_10_10_10_2,
8258 tm->hw[0]->sw_if_index);
8259
8260 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8261 .type = FT_LB_ADJ,
8262 .adj = {
8263 .adj = ai_10_10_10_2,
8264 },
8265 };
8266 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8267
8268 fei = fib_table_entry_path_add(0,
8269 &pfx_5_5_5_5_s_32,
8270 FIB_SOURCE_CLI,
8271 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008272 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008273 &nh_10_10_10_2,
8274 tm->hw[0]->sw_if_index,
8275 ~0, // invalid fib index
8276 1,
8277 NULL,
8278 FIB_ROUTE_PATH_FLAG_NONE);
8279
Neale Ranns2303cb12018-02-21 04:57:17 -08008280 FIB_TEST(!fib_test_validate_entry(fei,
8281 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8282 1,
8283 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008284 "BFD sourced %U via %U",
8285 format_fib_prefix, &pfx_5_5_5_5_s_32,
8286 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8287
8288 /*
8289 * Bring up the down session - should now LB
8290 */
8291 bfd_10_10_10_1.local_state = BFD_STATE_up;
8292 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008293 FIB_TEST(!fib_test_validate_entry(fei,
8294 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8295 2,
8296 &adj_o_10_10_10_1,
8297 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008298 "BFD sourced %U via noth adjs",
8299 format_fib_prefix, &pfx_5_5_5_5_s_32);
8300
8301 /*
8302 * remove the BFD session state from the adj
8303 */
8304 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8305
8306 /*
8307 * clean-up
8308 */
8309 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8310 adj_unlock(ai_10_10_10_1);
8311 adj_unlock(ai_10_10_10_2);
8312
8313 /*
8314 * test no-one left behind
8315 */
8316 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8317 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -08008318
8319 return (res);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008320}
8321
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008322static int
8323lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008324{
8325 const mpls_label_t deag_label = 50;
Neale Ranns2303cb12018-02-21 04:57:17 -08008326 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns31ed7442018-02-23 05:29:09 -08008327 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008328 const u32 lfib_index = 0;
8329 const u32 fib_index = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008330 const dpo_id_t *dpo1;
8331 fib_node_index_t lfe;
Neale Ranns2303cb12018-02-21 04:57:17 -08008332 lookup_dpo_t *lkd;
8333 int lb_count, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008334 test_main_t *tm;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008335
Neale Ranns2303cb12018-02-21 04:57:17 -08008336 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008337 tm = &test_main;
8338 lb_count = pool_elts(load_balance_pool);
8339
8340 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08008341 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008342
8343 /*
8344 * MPLS enable an interface so we get the MPLS table created
8345 */
Neale Ranns2297af02017-09-12 09:45:04 -07008346 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008347 mpls_sw_interface_enable_disable(&mpls_main,
8348 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008349 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008350
Neale Rannsad422ed2016-11-02 14:20:04 +00008351 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008352 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Rannsad422ed2016-11-02 14:20:04 +00008353 };
8354 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8355 VNET_LINK_MPLS,
8356 &nh_10_10_10_1,
8357 tm->hw[0]->sw_if_index);
8358
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008359 /*
8360 * Test the specials stack properly.
8361 */
8362 fib_prefix_t exp_null_v6_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008363 .fp_proto = FIB_PROTOCOL_MPLS,
8364 .fp_eos = MPLS_EOS,
8365 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8366 .fp_payload_proto = DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008367 };
8368 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8369 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
Neale Ranns2303cb12018-02-21 04:57:17 -08008370 "%U/%U present",
8371 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8372 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008373 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008374 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8375 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008376 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8377 lkd = lookup_dpo_get(dpo1->dpoi_index);
8378
8379 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008380 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008381 format_mpls_unicast_label, deag_label,
8382 format_mpls_eos_bit, MPLS_EOS,
8383 lkd->lkd_fib_index,
8384 format_dpo_id, &dpo, 0);
8385 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8386 "%U/%U is dst deag",
8387 format_mpls_unicast_label, deag_label,
8388 format_mpls_eos_bit, MPLS_EOS);
8389 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8390 "%U/%U is lookup in interface's table",
8391 format_mpls_unicast_label, deag_label,
8392 format_mpls_eos_bit, MPLS_EOS);
8393 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8394 "%U/%U is %U dst deag",
8395 format_mpls_unicast_label, deag_label,
8396 format_mpls_eos_bit, MPLS_EOS,
8397 format_dpo_proto, lkd->lkd_proto);
8398
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008399 /*
8400 * A route deag route for EOS
8401 */
8402 fib_prefix_t pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008403 .fp_proto = FIB_PROTOCOL_MPLS,
8404 .fp_eos = MPLS_EOS,
8405 .fp_label = deag_label,
8406 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008407 };
Neale Ranns2303cb12018-02-21 04:57:17 -08008408 mpls_disp_dpo_t *mdd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008409 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008410 &pfx,
8411 FIB_SOURCE_CLI,
8412 FIB_ENTRY_FLAG_NONE,
8413 DPO_PROTO_IP4,
8414 &zero_addr,
8415 ~0,
8416 fib_index,
8417 1,
8418 NULL,
8419 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008420
8421 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008422 "%U/%U present",
8423 format_mpls_unicast_label, deag_label,
8424 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008425
8426 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008427 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8428 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008429 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
Neale Ranns31ed7442018-02-23 05:29:09 -08008430 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8431
8432 FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode),
8433 "%U/%U disp is pipe mode",
8434 format_mpls_unicast_label, deag_label,
8435 format_mpls_eos_bit, MPLS_EOS);
8436
8437 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008438
8439 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008440 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008441 format_mpls_unicast_label, deag_label,
8442 format_mpls_eos_bit, MPLS_EOS,
8443 lkd->lkd_fib_index,
8444 format_dpo_id, &dpo, 0);
8445 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8446 "%U/%U is dst deag",
8447 format_mpls_unicast_label, deag_label,
8448 format_mpls_eos_bit, MPLS_EOS);
8449 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8450 "%U/%U is %U dst deag",
8451 format_mpls_unicast_label, deag_label,
8452 format_mpls_eos_bit, MPLS_EOS,
8453 format_dpo_proto, lkd->lkd_proto);
8454
8455 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8456
8457 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8458 &pfx)),
8459 "%U/%U not present",
8460 format_mpls_unicast_label, deag_label,
8461 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns31ed7442018-02-23 05:29:09 -08008462 dpo_reset(&dpo);
8463
8464 /*
8465 * A route deag route for EOS with LSP mode uniform
8466 */
8467 fib_mpls_label_t *l_pops = NULL, l_pop = {
8468 .fml_value = MPLS_LABEL_POP,
8469 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
8470 };
8471 vec_add1(l_pops, l_pop);
8472 lfe = fib_table_entry_path_add(lfib_index,
8473 &pfx,
8474 FIB_SOURCE_CLI,
8475 FIB_ENTRY_FLAG_NONE,
8476 DPO_PROTO_IP4,
8477 &zero_addr,
8478 ~0,
8479 fib_index,
8480 1,
8481 l_pops,
8482 FIB_ROUTE_PATH_FLAG_NONE);
8483
8484 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8485 "%U/%U present",
8486 format_mpls_unicast_label, deag_label,
8487 format_mpls_eos_bit, MPLS_EOS);
8488
8489 fib_entry_contribute_forwarding(lfe,
8490 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8491 &dpo);
8492 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8493 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8494
8495 FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode),
8496 "%U/%U disp is uniform mode",
8497 format_mpls_unicast_label, deag_label,
8498 format_mpls_eos_bit, MPLS_EOS);
8499
8500 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
8501
8502 FIB_TEST((fib_index == lkd->lkd_fib_index),
8503 "%U/%U is deag in %d %U",
8504 format_mpls_unicast_label, deag_label,
8505 format_mpls_eos_bit, MPLS_EOS,
8506 lkd->lkd_fib_index,
8507 format_dpo_id, &dpo, 0);
8508 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8509 "%U/%U is dst deag",
8510 format_mpls_unicast_label, deag_label,
8511 format_mpls_eos_bit, MPLS_EOS);
8512 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8513 "%U/%U is %U dst deag",
8514 format_mpls_unicast_label, deag_label,
8515 format_mpls_eos_bit, MPLS_EOS,
8516 format_dpo_proto, lkd->lkd_proto);
8517
8518 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8519
8520 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8521 &pfx)),
8522 "%U/%U not present",
8523 format_mpls_unicast_label, deag_label,
8524 format_mpls_eos_bit, MPLS_EOS);
8525 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008526
8527 /*
8528 * A route deag route for non-EOS
8529 */
8530 pfx.fp_eos = MPLS_NON_EOS;
8531 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008532 &pfx,
8533 FIB_SOURCE_CLI,
8534 FIB_ENTRY_FLAG_NONE,
8535 DPO_PROTO_IP4,
8536 &zero_addr,
8537 ~0,
8538 lfib_index,
8539 1,
8540 NULL,
8541 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008542
8543 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008544 "%U/%U present",
8545 format_mpls_unicast_label, deag_label,
8546 format_mpls_eos_bit, MPLS_NON_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008547
8548 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008549 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8550 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008551 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8552 lkd = lookup_dpo_get(dpo1->dpoi_index);
8553
8554 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008555 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008556 format_mpls_unicast_label, deag_label,
8557 format_mpls_eos_bit, MPLS_NON_EOS,
8558 lkd->lkd_fib_index,
8559 format_dpo_id, &dpo, 0);
8560 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8561 "%U/%U is dst deag",
8562 format_mpls_unicast_label, deag_label,
8563 format_mpls_eos_bit, MPLS_NON_EOS);
8564
8565 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8566 "%U/%U is %U dst deag",
8567 format_mpls_unicast_label, deag_label,
8568 format_mpls_eos_bit, MPLS_NON_EOS,
8569 format_dpo_proto, lkd->lkd_proto);
8570
8571 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8572
8573 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008574 &pfx)),
8575 "%U/%U not present",
8576 format_mpls_unicast_label, deag_label,
8577 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008578
Neale Rannsad422ed2016-11-02 14:20:04 +00008579 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008580
Neale Rannsad422ed2016-11-02 14:20:04 +00008581 /*
8582 * An MPLS x-connect
8583 */
8584 fib_prefix_t pfx_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008585 .fp_len = 21,
8586 .fp_proto = FIB_PROTOCOL_MPLS,
8587 .fp_label = 1200,
8588 .fp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008589 };
8590 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008591 .type = FT_LB_LABEL_STACK_O_ADJ,
8592 .label_stack_o_adj = {
8593 .adj = ai_mpls_10_10_10_1,
8594 .label_stack_size = 4,
8595 .label_stack = {
8596 200, 300, 400, 500,
8597 },
8598 .eos = MPLS_NON_EOS,
8599 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008600 };
8601 dpo_id_t neos_1200 = DPO_INVALID;
8602 dpo_id_t ip_1200 = DPO_INVALID;
Neale Ranns31ed7442018-02-23 05:29:09 -08008603 fib_mpls_label_t *l200 = NULL;
8604 u32 ii;
8605 for (ii = 0; ii < 4; ii++)
8606 {
8607 fib_mpls_label_t fml = {
8608 .fml_value = 200 + (ii * 100),
8609 };
8610 vec_add1(l200, fml);
8611 };
Neale Rannsad422ed2016-11-02 14:20:04 +00008612
8613 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008614 &pfx_1200,
8615 FIB_SOURCE_API,
8616 FIB_ENTRY_FLAG_NONE,
8617 DPO_PROTO_IP4,
8618 &nh_10_10_10_1,
8619 tm->hw[0]->sw_if_index,
8620 ~0, // invalid fib index
8621 1,
8622 l200,
8623 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00008624
Neale Ranns2303cb12018-02-21 04:57:17 -08008625 FIB_TEST(!fib_test_validate_entry(lfe,
8626 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8627 1,
8628 &neos_o_10_10_10_1),
8629 "1200/0 LB 1 buckets via: "
8630 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00008631
8632 /*
8633 * A recursive route via the MPLS x-connect
8634 */
8635 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008636 .fp_len = 32,
8637 .fp_proto = FIB_PROTOCOL_IP4,
8638 .fp_addr = {
8639 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8640 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008641 };
8642 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008643 .frp_proto = DPO_PROTO_MPLS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008644 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008645 .frp_eos = MPLS_NON_EOS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008646 .frp_sw_if_index = ~0, // recurive
8647 .frp_fib_index = 0, // Default MPLS fib
8648 .frp_weight = 1,
8649 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8650 .frp_label_stack = NULL,
Neale Rannsad422ed2016-11-02 14:20:04 +00008651 };
8652 vec_add1(rpaths, rpath);
8653
8654 fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008655 &pfx_2_2_2_3_s_32,
8656 FIB_SOURCE_API,
8657 FIB_ENTRY_FLAG_NONE,
8658 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008659
8660 /*
8661 * A labelled recursive route via the MPLS x-connect
8662 */
8663 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008664 .fp_len = 32,
8665 .fp_proto = FIB_PROTOCOL_IP4,
8666 .fp_addr = {
8667 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8668 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008669 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008670 fib_mpls_label_t *l999 = NULL, fml_999 = {
8671 .fml_value = 999,
8672 };
8673 vec_add1(l999, fml_999);
Neale Rannsad422ed2016-11-02 14:20:04 +00008674 rpaths[0].frp_label_stack = l999,
8675
Neale Ranns2303cb12018-02-21 04:57:17 -08008676 fib_table_entry_path_add2(fib_index,
8677 &pfx_2_2_2_4_s_32,
8678 FIB_SOURCE_API,
8679 FIB_ENTRY_FLAG_NONE,
8680 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008681
8682 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008683 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8684 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008685 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008686 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8687 &neos_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008688
8689 fib_test_lb_bucket_t ip_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008690 .type = FT_LB_O_LB,
8691 .lb = {
8692 .lb = ip_1200.dpoi_index,
8693 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008694 };
8695 fib_test_lb_bucket_t mpls_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008696 .type = FT_LB_LABEL_O_LB,
8697 .label_o_lb = {
8698 .lb = neos_1200.dpoi_index,
8699 .label = 999,
8700 .eos = MPLS_EOS,
8701 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008702 };
8703
8704 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008705 FIB_TEST(!fib_test_validate_entry(lfe,
8706 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8707 1,
8708 &ip_o_1200),
8709 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008710 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008711 FIB_TEST(!fib_test_validate_entry(lfe,
8712 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8713 1,
8714 &mpls_o_1200),
8715 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008716
8717 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8718 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8719 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8720
8721 dpo_reset(&neos_1200);
8722 dpo_reset(&ip_1200);
8723
8724 /*
8725 * A recursive via a label that does not exist
8726 */
8727 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008728 .type = FT_LB_DROP,
8729 .special = {
8730 .adj = DPO_PROTO_IP4,
8731 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07008732 };
8733 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008734 .type = FT_LB_DROP,
8735 .special = {
8736 .adj = DPO_PROTO_MPLS,
8737 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008738 };
8739
8740 rpaths[0].frp_label_stack = NULL;
8741 lfe = fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008742 &pfx_2_2_2_4_s_32,
8743 FIB_SOURCE_API,
8744 FIB_ENTRY_FLAG_NONE,
8745 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008746
8747 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008748 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8749 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008750 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8751
Neale Ranns2303cb12018-02-21 04:57:17 -08008752 FIB_TEST(!fib_test_validate_entry(lfe,
8753 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8754 1,
8755 &bucket_drop),
8756 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008757 lfe = fib_table_lookup(fib_index, &pfx_1200);
Neale Ranns2303cb12018-02-21 04:57:17 -08008758 FIB_TEST(!fib_test_validate_entry(lfe,
8759 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8760 1,
8761 &bucket_drop),
8762 "1200/neos LB 1 buckets via: ip4-DROP");
8763 FIB_TEST(!fib_test_validate_entry(lfe,
8764 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8765 1,
8766 &mpls_bucket_drop),
8767 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008768
8769 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8770
8771 dpo_reset(&ip_1200);
8772
8773 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008774 * An rx-interface route.
8775 * like the tail of an mcast LSP
8776 */
8777 dpo_id_t idpo = DPO_INVALID;
8778
Neale Ranns43161a82017-08-12 02:12:00 -07008779 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08008780 tm->hw[0]->sw_if_index,
8781 &idpo);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008782
8783 fib_prefix_t pfx_2500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008784 .fp_len = 21,
8785 .fp_proto = FIB_PROTOCOL_MPLS,
8786 .fp_label = 2500,
8787 .fp_eos = MPLS_EOS,
8788 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008789 };
8790 fib_test_lb_bucket_t rx_intf_0 = {
8791 .type = FT_LB_INTF,
8792 .adj = {
8793 .adj = idpo.dpoi_index,
8794 },
8795 };
8796
8797 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008798 &pfx_2500,
8799 FIB_SOURCE_API,
8800 FIB_ENTRY_FLAG_NONE,
8801 DPO_PROTO_IP4,
8802 NULL,
8803 tm->hw[0]->sw_if_index,
8804 ~0, // invalid fib index
8805 0,
8806 NULL,
8807 FIB_ROUTE_PATH_INTF_RX);
8808 FIB_TEST(!fib_test_validate_entry(lfe,
8809 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8810 1,
8811 &rx_intf_0),
8812 "2500 rx-interface 0");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008813 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8814
8815 /*
8816 * An MPLS mulicast entry
8817 */
8818 fib_prefix_t pfx_3500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008819 .fp_len = 21,
8820 .fp_proto = FIB_PROTOCOL_MPLS,
8821 .fp_label = 3500,
8822 .fp_eos = MPLS_EOS,
8823 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008824 };
8825 fib_test_rep_bucket_t mc_0 = {
8826 .type = FT_REP_LABEL_O_ADJ,
Neale Ranns2303cb12018-02-21 04:57:17 -08008827 .label_o_adj = {
8828 .adj = ai_mpls_10_10_10_1,
8829 .label = 3300,
8830 .eos = MPLS_EOS,
8831 },
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008832 };
8833 fib_test_rep_bucket_t mc_intf_0 = {
8834 .type = FT_REP_INTF,
8835 .adj = {
8836 .adj = idpo.dpoi_index,
8837 },
8838 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008839 fib_mpls_label_t *l3300 = NULL, fml_3300 = {
8840 .fml_value = 3300,
8841 };
8842 vec_add1(l3300, fml_3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008843
8844 lfe = fib_table_entry_update_one_path(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008845 &pfx_3500,
8846 FIB_SOURCE_API,
8847 FIB_ENTRY_FLAG_MULTICAST,
8848 DPO_PROTO_IP4,
8849 &nh_10_10_10_1,
8850 tm->hw[0]->sw_if_index,
8851 ~0, // invalid fib index
8852 1,
8853 l3300,
8854 FIB_ROUTE_PATH_FLAG_NONE);
8855 FIB_TEST(!fib_test_validate_entry(lfe,
8856 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8857 1,
8858 &mc_0),
8859 "3500 via replicate over 10.10.10.1");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008860
8861 /*
8862 * MPLS Bud-node. Add a replication via an interface-receieve path
8863 */
8864 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008865 &pfx_3500,
8866 FIB_SOURCE_API,
8867 FIB_ENTRY_FLAG_MULTICAST,
8868 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008869 NULL,
8870 tm->hw[0]->sw_if_index,
8871 ~0, // invalid fib index
8872 0,
8873 NULL,
8874 FIB_ROUTE_PATH_INTF_RX);
Neale Ranns2303cb12018-02-21 04:57:17 -08008875 FIB_TEST(!fib_test_validate_entry(lfe,
8876 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8877 2,
8878 &mc_0,
8879 &mc_intf_0),
8880 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008881
8882 /*
8883 * Add a replication via an interface-free for-us path
8884 */
8885 fib_test_rep_bucket_t mc_disp = {
8886 .type = FT_REP_DISP_MFIB_LOOKUP,
8887 .adj = {
8888 .adj = idpo.dpoi_index,
8889 },
8890 };
8891 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008892 &pfx_3500,
8893 FIB_SOURCE_API,
8894 FIB_ENTRY_FLAG_MULTICAST,
8895 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008896 NULL,
8897 5, // rpf-id
8898 0, // default table
8899 0,
8900 NULL,
8901 FIB_ROUTE_PATH_RPF_ID);
Neale Ranns2303cb12018-02-21 04:57:17 -08008902 FIB_TEST(!fib_test_validate_entry(lfe,
8903 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8904 3,
8905 &mc_0,
8906 &mc_disp,
8907 &mc_intf_0),
8908 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008909
8910
Neale Ranns2303cb12018-02-21 04:57:17 -08008911
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008912 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8913 dpo_reset(&idpo);
8914
8915 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008916 * cleanup
8917 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008918 mpls_sw_interface_enable_disable(&mpls_main,
8919 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008920 0, 1);
8921 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008922
Neale Ranns31ed7442018-02-23 05:29:09 -08008923 FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
8924 "mpls_disp_dpo resources freed %d of %d",
8925 0, pool_elts(mpls_disp_dpo_pool));
Neale Rannsad422ed2016-11-02 14:20:04 +00008926 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008927 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008928 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008929 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008930 "interface_rx_dpo resources freed %d of %d",
Neale Ranns43161a82017-08-12 02:12:00 -07008931 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008932
Neale Ranns2303cb12018-02-21 04:57:17 -08008933 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008934}
8935
Neale Ranns89541992017-04-06 04:41:02 -07008936static int
8937fib_test_inherit (void)
8938{
8939 fib_node_index_t fei;
8940 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08008941 int n_feis, res;
Neale Ranns89541992017-04-06 04:41:02 -07008942
Neale Ranns2303cb12018-02-21 04:57:17 -08008943 res = 0;
Neale Ranns89541992017-04-06 04:41:02 -07008944 n_feis = fib_entry_pool_size();
8945 tm = &test_main;
8946
8947 const ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008948 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Ranns89541992017-04-06 04:41:02 -07008949 };
8950 const ip46_address_t nh_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008951 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8952 };
8953 const ip46_address_t nh_10_10_10_3 = {
8954 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
Neale Ranns89541992017-04-06 04:41:02 -07008955 };
8956 const ip46_address_t nh_10_10_10_16 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008957 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
Neale Ranns89541992017-04-06 04:41:02 -07008958 };
8959 const ip46_address_t nh_10_10_10_20 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008960 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
Neale Ranns89541992017-04-06 04:41:02 -07008961 };
8962 const ip46_address_t nh_10_10_10_21 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008963 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
Neale Ranns89541992017-04-06 04:41:02 -07008964 };
8965 const ip46_address_t nh_10_10_10_22 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008966 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
Neale Ranns89541992017-04-06 04:41:02 -07008967 };
8968 const ip46_address_t nh_10_10_10_255 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008969 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
Neale Ranns89541992017-04-06 04:41:02 -07008970 };
8971 const ip46_address_t nh_10_10_10_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008972 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
Neale Ranns89541992017-04-06 04:41:02 -07008973 };
8974 const ip46_address_t nh_10_10_0_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008975 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8976 };
8977 const ip46_address_t nh_11_11_11_11 = {
8978 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
8979 };
8980 const ip46_address_t nh_11_11_11_0 = {
8981 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b00),
Neale Ranns89541992017-04-06 04:41:02 -07008982 };
8983
8984 /*
8985 * prefixes at the base of a sub-tree
8986 */
8987 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8988 .fp_len = 32,
8989 .fp_proto = FIB_PROTOCOL_IP4,
8990 .fp_addr = nh_10_10_10_21,
8991 };
8992 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8993 .fp_len = 32,
8994 .fp_proto = FIB_PROTOCOL_IP4,
8995 .fp_addr = nh_10_10_10_22,
8996 };
8997 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8998 .fp_len = 32,
8999 .fp_proto = FIB_PROTOCOL_IP4,
9000 .fp_addr = nh_10_10_10_255,
9001 };
Neale Ranns2303cb12018-02-21 04:57:17 -08009002 const u32 N_PLS = fib_path_list_pool_size();
Neale Ranns89541992017-04-06 04:41:02 -07009003
9004 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009005 &pfx_10_10_10_21_s_32,
9006 FIB_SOURCE_CLI,
9007 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009008 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009009 &pfx_10_10_10_22_s_32,
9010 FIB_SOURCE_CLI,
9011 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009012 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009013 &pfx_10_10_10_255_s_32,
9014 FIB_SOURCE_CLI,
9015 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009016
9017 /*
9018 * source an entry that pushes its state down the sub-tree
9019 */
9020 const fib_prefix_t pfx_10_10_10_16_s_28 = {
9021 .fp_len = 28,
9022 .fp_proto = FIB_PROTOCOL_IP4,
9023 .fp_addr = nh_10_10_10_16,
9024 };
9025 fib_table_entry_update_one_path(0,
9026 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009027 FIB_SOURCE_API,
9028 FIB_ENTRY_FLAG_COVERED_INHERIT,
9029 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009030 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009031 tm->hw[0]->sw_if_index,
9032 ~0,
9033 1,
9034 NULL,
9035 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009036
9037 /*
9038 * this covering entry and all those below it should have
9039 * the same forwarding information.
9040 */
9041 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9042 VNET_LINK_IP4,
9043 &nh_10_10_10_1,
9044 tm->hw[0]->sw_if_index);
9045 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009046 .type = FT_LB_ADJ,
9047 .adj = {
9048 .adj = ai_10_10_10_1,
9049 },
Neale Ranns89541992017-04-06 04:41:02 -07009050 };
9051
9052 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
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_16_s_28);
9059 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_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_21_s_32);
9066 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009067 FIB_TEST(!fib_test_validate_entry(fei,
9068 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9069 1,
9070 &adj_o_10_10_10_1),
9071 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009072 format_fib_prefix, &pfx_10_10_10_22_s_32);
9073 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9074 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9075 "%U resolves via drop",
9076 format_fib_prefix, &pfx_10_10_10_255_s_32);
9077
9078 /*
9079 * remove the inherting cover - covereds go back to drop
9080 */
9081 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9082
9083 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9084 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9085 "%U resolves via drop",
9086 format_fib_prefix, &pfx_10_10_10_21_s_32);
9087
9088 /*
9089 * source an entry that pushes its state down the sub-tree
9090 */
9091 const fib_prefix_t pfx_10_10_10_0_s_24 = {
9092 .fp_len = 24,
9093 .fp_proto = FIB_PROTOCOL_IP4,
9094 .fp_addr = nh_10_10_10_0,
9095 };
9096 fib_table_entry_update_one_path(0,
9097 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009098 FIB_SOURCE_API,
9099 FIB_ENTRY_FLAG_COVERED_INHERIT,
9100 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009101 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009102 tm->hw[0]->sw_if_index,
9103 ~0,
9104 1,
9105 NULL,
9106 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009107
9108 /*
9109 * whole sub-tree now covered
9110 */
9111 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
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_0_s_24);
9118 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_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_21_s_32);
9125 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9132 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009133 FIB_TEST(!fib_test_validate_entry(fei,
9134 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9135 1,
9136 &adj_o_10_10_10_1),
9137 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009138 format_fib_prefix, &pfx_10_10_10_255_s_32);
9139
9140 /*
9141 * insert a more specific into the sub-tree - expect inheritance
9142 * this one is directly covered by the root
9143 */
9144 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009145 &pfx_10_10_10_16_s_28,
9146 FIB_SOURCE_CLI,
9147 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009148 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009149 FIB_TEST(!fib_test_validate_entry(fei,
9150 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9151 1,
9152 &adj_o_10_10_10_1),
9153 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009154 format_fib_prefix, &pfx_10_10_10_16_s_28);
9155
9156 /*
9157 * insert a more specific into the sub-tree - expect inheritance
9158 * this one is indirectly covered by the root
9159 */
9160 const fib_prefix_t pfx_10_10_10_20_s_30 = {
9161 .fp_len = 30,
9162 .fp_proto = FIB_PROTOCOL_IP4,
9163 .fp_addr = nh_10_10_10_20,
9164 };
9165 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009166 &pfx_10_10_10_20_s_30,
9167 FIB_SOURCE_CLI,
9168 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009169 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
Neale Ranns2303cb12018-02-21 04:57:17 -08009170 FIB_TEST(!fib_test_validate_entry(fei,
9171 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9172 1,
9173 &adj_o_10_10_10_1),
9174 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009175 format_fib_prefix, &pfx_10_10_10_20_s_30);
9176
9177 /*
9178 * remove the prefix from the middle of the sub-tree
9179 * the inherited source will be the only one remaining - expect
9180 * it to be withdrawn and hence the prefix is removed.
9181 */
9182 fib_table_entry_special_remove(0,
9183 &pfx_10_10_10_20_s_30,
9184 FIB_SOURCE_CLI);
9185 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9186 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9187 "%U gone",
9188 format_fib_prefix, &pfx_10_10_10_20_s_30);
9189
9190 /*
9191 * inheriting source is modifed - expect the modification to be present
9192 * throughout the sub-tree
9193 */
9194 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9195 VNET_LINK_IP4,
9196 &nh_10_10_10_2,
9197 tm->hw[0]->sw_if_index);
9198 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009199 .type = FT_LB_ADJ,
9200 .adj = {
9201 .adj = ai_10_10_10_2,
9202 },
Neale Ranns89541992017-04-06 04:41:02 -07009203 };
9204
9205 fib_table_entry_update_one_path(0,
9206 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009207 FIB_SOURCE_API,
9208 FIB_ENTRY_FLAG_COVERED_INHERIT,
9209 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009210 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009211 tm->hw[0]->sw_if_index,
9212 ~0,
9213 1,
9214 NULL,
9215 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009216 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_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_21_s_32);
9223 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9230 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9237 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009238 FIB_TEST(!fib_test_validate_entry(fei,
9239 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9240 1,
9241 &adj_o_10_10_10_2),
9242 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009243 format_fib_prefix, &pfx_10_10_10_0_s_24);
9244
9245 /*
9246 * add the source that replaces inherited state.
9247 * inheriting source is not the best, so it doesn't push state.
9248 */
9249 fib_table_entry_update_one_path(0,
9250 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009251 FIB_SOURCE_PLUGIN_HI,
9252 FIB_ENTRY_FLAG_NONE,
9253 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009254 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009255 tm->hw[0]->sw_if_index,
9256 ~0,
9257 1,
9258 NULL,
9259 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009260 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009261 FIB_TEST(!fib_test_validate_entry(fei,
9262 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9263 1,
9264 &adj_o_10_10_10_1),
9265 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009266 format_fib_prefix, &pfx_10_10_10_0_s_24);
9267
9268 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9269 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9270 "%U resolves via drop",
9271 format_fib_prefix, &pfx_10_10_10_21_s_32);
9272 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
9273 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9274 "%U resolves via drop",
9275 format_fib_prefix, &pfx_10_10_10_22_s_32);
9276 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9277 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9278 "%U resolves via drop",
9279 format_fib_prefix, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009280 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009281 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9282 "%U resolves via drop",
9283 format_fib_prefix, &pfx_10_10_10_16_s_28);
9284
9285 /*
9286 * withdraw the higher priority source and expect the inherited to return
9287 * throughout the sub-tree
9288 */
9289 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9290
9291 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_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_21_s_32);
9298 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9305 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9312 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
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_0_s_24);
9319 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009320 FIB_TEST(!fib_test_validate_entry(fei,
9321 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9322 1,
9323 &adj_o_10_10_10_2),
9324 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009325 format_fib_prefix, &pfx_10_10_10_16_s_28);
9326
9327 /*
9328 * source a covered entry in the sub-tree with the same inherting source
9329 * - expect that it now owns the sub-tree and thus over-rides its cover
9330 */
9331 fib_table_entry_update_one_path(0,
9332 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009333 FIB_SOURCE_API,
9334 FIB_ENTRY_FLAG_COVERED_INHERIT,
9335 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009336 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009337 tm->hw[0]->sw_if_index,
9338 ~0,
9339 1,
9340 NULL,
9341 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009342 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
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.1",
Neale Ranns89541992017-04-06 04:41:02 -07009348 format_fib_prefix, &pfx_10_10_10_16_s_28);
9349 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9356 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009357 FIB_TEST(!fib_test_validate_entry(fei,
9358 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9359 1,
9360 &adj_o_10_10_10_1),
9361 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009362 format_fib_prefix, &pfx_10_10_10_21_s_32);
9363
9364 /* these two unaffected by the sub-tree change */
9365 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9372 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009373 FIB_TEST(!fib_test_validate_entry(fei,
9374 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9375 1,
9376 &adj_o_10_10_10_2),
9377 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009378 format_fib_prefix, &pfx_10_10_10_0_s_24);
9379
9380 /*
9381 * removes the more specific, expect the /24 to now re-owns the sub-tree
9382 */
9383 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9384
9385 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009386 FIB_TEST(!fib_test_validate_entry(fei,
9387 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9388 1,
9389 &adj_o_10_10_10_2),
9390 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009391 format_fib_prefix, &pfx_10_10_10_16_s_28);
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_21_s_32);
9398 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9405 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9412 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009413 FIB_TEST(!fib_test_validate_entry(fei,
9414 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9415 1,
9416 &adj_o_10_10_10_2),
9417 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009418 format_fib_prefix, &pfx_10_10_10_0_s_24);
9419 /*
9420 * modify the /24. expect the new forwarding to be pushed down
9421 */
9422 fib_table_entry_update_one_path(0,
9423 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009424 FIB_SOURCE_API,
9425 FIB_ENTRY_FLAG_COVERED_INHERIT,
9426 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009427 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009428 tm->hw[0]->sw_if_index,
9429 ~0,
9430 1,
9431 NULL,
9432 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009433 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009434 FIB_TEST(!fib_test_validate_entry(fei,
9435 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9436 1,
9437 &adj_o_10_10_10_1),
9438 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009439 format_fib_prefix, &pfx_10_10_10_16_s_28);
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_21_s_32);
9446 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9453 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9460 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009461 FIB_TEST(!fib_test_validate_entry(fei,
9462 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9463 1,
9464 &adj_o_10_10_10_1),
9465 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009466 format_fib_prefix, &pfx_10_10_10_0_s_24);
9467
9468 /*
9469 * add an entry less specific to /24. it should not own the /24's tree
9470 */
9471 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9472 .fp_len = 16,
9473 .fp_proto = FIB_PROTOCOL_IP4,
9474 .fp_addr = nh_10_10_0_0,
9475 };
9476 fib_table_entry_update_one_path(0,
9477 &pfx_10_10_0_0_s_16,
Neale Ranns2303cb12018-02-21 04:57:17 -08009478 FIB_SOURCE_API,
9479 FIB_ENTRY_FLAG_COVERED_INHERIT,
9480 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009481 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009482 tm->hw[0]->sw_if_index,
9483 ~0,
9484 1,
9485 NULL,
9486 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009487 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_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_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009494 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9501 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
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_255_s_32);
9508 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
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_1),
9513 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009514 format_fib_prefix, &pfx_10_10_10_0_s_24);
9515 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
Neale Ranns2303cb12018-02-21 04:57:17 -08009516 FIB_TEST(!fib_test_validate_entry(fei,
9517 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9518 1,
9519 &adj_o_10_10_10_2),
9520 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009521 format_fib_prefix, &pfx_10_10_0_0_s_16);
9522
9523 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08009524 * Add/remove an interposer source to a new /32
9525 */
9526 const fib_prefix_t pfx_11_11_11_11_s_32 = {
9527 .fp_len = 32,
9528 .fp_proto = FIB_PROTOCOL_IP4,
9529 .fp_addr = nh_11_11_11_11,
9530 };
9531
9532 fib_table_entry_update_one_path(0,
9533 &pfx_11_11_11_11_s_32,
9534 FIB_SOURCE_API,
9535 FIB_ENTRY_FLAG_NONE,
9536 DPO_PROTO_IP4,
9537 &nh_10_10_10_3,
9538 tm->hw[0]->sw_if_index,
9539 ~0,
9540 1,
9541 NULL,
9542 FIB_ROUTE_PATH_FLAG_NONE);
9543
9544 dpo_id_t interposer = DPO_INVALID;
9545 fib_mpls_label_t *l99 = NULL, fml_99 = {
9546 .fml_value = 99,
9547 };
9548 vec_add1(l99, fml_99);
9549
9550 mpls_label_dpo_create(l99,
9551 MPLS_EOS,
9552 DPO_PROTO_IP4,
9553 MPLS_LABEL_DPO_FLAG_NONE,
9554 punt_dpo_get(DPO_PROTO_MPLS),
9555 &interposer);
9556
9557 adj_index_t ai_10_10_10_3 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9558 VNET_LINK_IP4,
9559 &nh_10_10_10_3,
9560 tm->hw[0]->sw_if_index);
9561 fib_test_lb_bucket_t adj_o_10_10_10_3 = {
9562 .type = FT_LB_ADJ,
9563 .adj = {
9564 .adj = ai_10_10_10_3,
9565 },
9566 };
9567 fib_test_lb_bucket_t l99_o_10_10_10_3 = {
9568 .type = FT_LB_LABEL_O_ADJ,
9569 .label_o_adj = {
9570 .adj = ai_10_10_10_3,
9571 .label = 99,
9572 .eos = MPLS_EOS,
9573 },
9574 };
9575
9576 fei = fib_table_entry_special_dpo_add(0,
9577 &pfx_11_11_11_11_s_32,
9578 FIB_SOURCE_SPECIAL,
9579 FIB_ENTRY_FLAG_INTERPOSE,
9580 &interposer);
9581 FIB_TEST(!fib_test_validate_entry(fei,
9582 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9583 1,
9584 &l99_o_10_10_10_3),
9585 "%U via interposer adj",
9586 format_fib_prefix,&pfx_11_11_11_11_s_32);
9587
9588 fib_table_entry_special_remove(0,
9589 &pfx_11_11_11_11_s_32,
9590 FIB_SOURCE_SPECIAL);
9591 FIB_TEST(!fib_test_validate_entry(fei,
9592 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9593 1,
9594 &adj_o_10_10_10_3),
9595 "%U via 10.10.10.1",
9596 format_fib_prefix, &pfx_11_11_11_11_s_32);
9597
9598 /*
9599 * remove and re-add the second best API source while the interpose
9600 * is present
9601 */
9602 fei = fib_table_entry_special_dpo_add(0,
9603 &pfx_11_11_11_11_s_32,
9604 FIB_SOURCE_SPECIAL,
9605 FIB_ENTRY_FLAG_INTERPOSE,
9606 &interposer);
9607 FIB_TEST(!fib_test_validate_entry(fei,
9608 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9609 1,
9610 &l99_o_10_10_10_3),
9611 "%U via interposer adj",
9612 format_fib_prefix,&pfx_11_11_11_11_s_32);
9613
9614 FIB_TEST(2 == pool_elts(mpls_label_dpo_pool),
9615 "MPLS label pool: %d",
9616 pool_elts(mpls_label_dpo_pool));
9617
9618 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9619
9620 /*
9621 * the interpose does not get stacked when there are not valid paths
9622 */
9623 fib_test_lb_bucket_t bucket_drop = {
9624 .type = FT_LB_DROP,
9625 .special = {
9626 .adj = DPO_PROTO_IP4,
9627 },
9628 };
9629 FIB_TEST(!fib_test_validate_entry(fei,
9630 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9631 1,
9632 &bucket_drop),
9633 "%U via drop",
9634 format_fib_prefix,&pfx_11_11_11_11_s_32);
9635
9636 fib_table_entry_update_one_path(0,
9637 &pfx_11_11_11_11_s_32,
9638 FIB_SOURCE_API,
9639 FIB_ENTRY_FLAG_NONE,
9640 DPO_PROTO_IP4,
9641 &nh_10_10_10_3,
9642 tm->hw[0]->sw_if_index,
9643 ~0,
9644 1,
9645 NULL,
9646 FIB_ROUTE_PATH_FLAG_NONE);
9647 FIB_TEST(!fib_test_validate_entry(fei,
9648 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9649 1,
9650 &l99_o_10_10_10_3),
9651 "%U via interposer adj",
9652 format_fib_prefix,&pfx_11_11_11_11_s_32);
9653 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9654
9655 /*
9656 * add a cover for the interposed entry, so that we test it selects
9657 * the covers forwarding.
9658 */
9659 const fib_prefix_t pfx_11_11_11_0_s_24 = {
9660 .fp_len = 24,
9661 .fp_proto = FIB_PROTOCOL_IP4,
9662 .fp_addr = nh_11_11_11_0,
9663 };
9664 fib_table_entry_update_one_path(0,
9665 &pfx_11_11_11_0_s_24,
9666 FIB_SOURCE_API,
9667 FIB_ENTRY_FLAG_NONE,
9668 DPO_PROTO_IP4,
9669 &nh_10_10_10_3,
9670 tm->hw[0]->sw_if_index,
9671 ~0,
9672 1,
9673 NULL,
9674 FIB_ROUTE_PATH_FLAG_NONE);
9675 FIB_TEST(!fib_test_validate_entry(fei,
9676 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9677 1,
9678 &l99_o_10_10_10_3),
9679 "%U via interposer adj",
9680 format_fib_prefix,&pfx_11_11_11_11_s_32);
9681
9682 /*
9683 * multiple interpose sources on the same entry. Only the high
9684 * priority source gets to add the interpose.
9685 */
9686 dpo_id_t interposer2 = DPO_INVALID;
9687 fib_mpls_label_t *l100 = NULL, fml_100 = {
9688 .fml_value = 100,
9689 };
9690 vec_add1(l100, fml_100);
9691
9692 mpls_label_dpo_create(l100,
9693 MPLS_EOS,
9694 DPO_PROTO_IP4,
9695 MPLS_LABEL_DPO_FLAG_NONE,
9696 punt_dpo_get(DPO_PROTO_MPLS),
9697 &interposer2);
9698
9699 fei = fib_table_entry_special_dpo_add(0,
9700 &pfx_11_11_11_11_s_32,
9701 FIB_SOURCE_CLASSIFY,
9702 FIB_ENTRY_FLAG_INTERPOSE,
9703 &interposer2);
9704 FIB_TEST(!fib_test_validate_entry(fei,
9705 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9706 1,
9707 &l99_o_10_10_10_3),
9708 "%U via interposer label 99",
9709 format_fib_prefix,&pfx_11_11_11_11_s_32);
9710
9711 fib_test_lb_bucket_t l100_o_10_10_10_3 = {
9712 .type = FT_LB_LABEL_O_ADJ,
9713 .label_o_adj = {
9714 .adj = ai_10_10_10_3,
9715 .label = 100,
9716 .eos = MPLS_EOS,
9717 },
9718 };
9719
9720 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_SPECIAL);
9721
9722 FIB_TEST(!fib_test_validate_entry(fei,
9723 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9724 1,
9725 &l100_o_10_10_10_3),
9726 "%U via interposer label 99",
9727 format_fib_prefix,&pfx_11_11_11_11_s_32);
9728
9729 fib_table_entry_delete(0, &pfx_11_11_11_0_s_24, FIB_SOURCE_API);
9730 FIB_TEST(!fib_test_validate_entry(fei,
9731 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9732 1,
9733 &bucket_drop),
9734 "%U via drop",
9735 format_fib_prefix,&pfx_11_11_11_11_s_32);
9736 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_CLASSIFY);
9737
9738 /*
9739 * update a source to/from interpose.
9740 */
9741 /* fib_table_entry_update_one_path(0, */
9742 /* &pfx_11_11_11_0_s_24, */
9743 /* FIB_SOURCE_API, */
9744 /* FIB_ENTRY_FLAG_NONE, */
9745 /* DPO_PROTO_IP4, */
9746 /* &nh_10_10_10_3, */
9747 /* tm->hw[0]->sw_if_index, */
9748 /* ~0, */
9749 /* 1, */
9750 /* NULL, */
9751 /* FIB_ROUTE_PATH_FLAG_NONE); */
9752 /* fei = fib_table_entry_special_dpo_add(0, */
9753 /* &pfx_11_11_11_11_s_32, */
9754 /* FIB_SOURCE_API, */
9755 /* FIB_ENTRY_FLAG_INTERPOSE, */
9756 /* &interposer); */
9757 /* FIB_TEST(!fib_test_validate_entry(fei, */
9758 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9759 /* 1, */
9760 /* &l99_o_10_10_10_3), */
9761 /* "%U via interposer label 99", */
9762 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9763
9764 /* FIB_TEST(3 == pool_elts(mpls_label_dpo_pool), */
9765 /* "MPLS label pool: %d", */
9766 /* pool_elts(mpls_label_dpo_pool)); */
9767 /* FIB_TEST((2 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9768 /* "Interposer %d locks", */
9769 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9770
9771 /* fib_table_entry_update_one_path(0, */
9772 /* &pfx_11_11_11_11_s_32, */
9773 /* FIB_SOURCE_API, */
9774 /* FIB_ENTRY_FLAG_NONE, */
9775 /* DPO_PROTO_IP4, */
9776 /* &nh_10_10_10_2, */
9777 /* tm->hw[0]->sw_if_index, */
9778 /* ~0, */
9779 /* 1, */
9780 /* NULL, */
9781 /* FIB_ROUTE_PATH_FLAG_NONE); */
9782 /* FIB_TEST(!fib_test_validate_entry(fei, */
9783 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9784 /* 1, */
9785 /* &adj_o_10_10_10_2), */
9786 /* "%U via 10.10.10.2", */
9787 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9788
9789 /* FIB_TEST((1 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9790 /* "Interposer %d locks", */
9791 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9792 /* FIB_TEST(2 == pool_elts(mpls_label_dpo_pool), */
9793 /* "MPLS label pool: %d", */
9794 /* pool_elts(mpls_label_dpo_pool)); */
9795
9796 /* fei = fib_table_entry_special_dpo_add(0, */
9797 /* &pfx_11_11_11_11_s_32, */
9798 /* FIB_SOURCE_API, */
9799 /* FIB_ENTRY_FLAG_INTERPOSE, */
9800 /* &interposer); */
9801 /* FIB_TEST(!fib_test_validate_entry(fei, */
9802 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9803 /* 1, */
9804 /* &l99_o_10_10_10_3), */
9805 /* "%U via interposer label 99", */
9806 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9807
9808 /* fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API); */
9809
9810 /*
9811 * Add/remove an interposer source from the top of the subtrie. The
9812 * interposer source is not inherited.
9813 */
9814 fib_table_entry_update_one_path(0,
9815 &pfx_10_10_10_0_s_24,
9816 FIB_SOURCE_API,
9817 FIB_ENTRY_FLAG_COVERED_INHERIT,
9818 DPO_PROTO_IP4,
9819 &nh_10_10_10_3,
9820 tm->hw[0]->sw_if_index,
9821 ~0,
9822 1,
9823 NULL,
9824 FIB_ROUTE_PATH_FLAG_NONE);
9825 fei = fib_table_entry_special_dpo_add(0,
9826 &pfx_10_10_10_0_s_24,
9827 FIB_SOURCE_SPECIAL,
9828 FIB_ENTRY_FLAG_INTERPOSE,
9829 &interposer);
9830 FIB_TEST(!fib_test_validate_entry(fei,
9831 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9832 1,
9833 &l99_o_10_10_10_3),
9834 "%U via interposer label",
9835 format_fib_prefix,&pfx_10_10_10_0_s_24);
9836 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9837 FIB_TEST(!fib_test_validate_entry(fei,
9838 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9839 1,
9840 &bucket_drop),
9841 "%U via drop",
9842 format_fib_prefix, &pfx_10_10_10_21_s_32);
9843
9844 fib_table_entry_special_remove(0,
9845 &pfx_10_10_10_0_s_24,
9846 FIB_SOURCE_SPECIAL);
9847 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
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 10.10.10.1",
9853 format_fib_prefix, &pfx_10_10_10_0_s_24);
9854 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9855 FIB_TEST(!fib_test_validate_entry(fei,
9856 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9857 1,
9858 &adj_o_10_10_10_3),
9859 "%U via via 10.10.10.1",
9860 format_fib_prefix, &pfx_10_10_10_21_s_32);
9861
9862 /*
9863 * Add/remove an interposer source from the top of the subtrie. The
9864 * interposer source is inherited.
9865 */
9866 fei = fib_table_entry_special_dpo_add(0,
9867 &pfx_10_10_10_0_s_24,
9868 FIB_SOURCE_SPECIAL,
9869 (FIB_ENTRY_FLAG_COVERED_INHERIT |
9870 FIB_ENTRY_FLAG_INTERPOSE),
9871 &interposer);
9872 FIB_TEST(!fib_test_validate_entry(fei,
9873 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9874 1,
9875 &l99_o_10_10_10_3),
9876 "%U via interposer label",
9877 format_fib_prefix,&pfx_10_10_10_0_s_24);
9878
9879 /* interposer gets forwarding from the drop cli source */
9880 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9881 FIB_TEST(!fib_test_validate_entry(fei,
9882 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9883 1,
9884 &bucket_drop),
9885 "%U via drop",
9886 format_fib_prefix,&pfx_10_10_10_21_s_32);
9887
9888 fib_table_entry_update_one_path(0,
9889 &pfx_10_10_10_21_s_32,
9890 FIB_SOURCE_API,
9891 FIB_ENTRY_FLAG_NONE,
9892 DPO_PROTO_IP4,
9893 &nh_10_10_10_3,
9894 tm->hw[0]->sw_if_index,
9895 ~0,
9896 1,
9897 NULL,
9898 FIB_ROUTE_PATH_FLAG_NONE);
9899 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9900 /* interposer gets forwarding from the API source */
9901 FIB_TEST(!fib_test_validate_entry(fei,
9902 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9903 1,
9904 &l99_o_10_10_10_3),
9905 "%U via interposer label",
9906 format_fib_prefix,&pfx_10_10_10_21_s_32);
9907
9908 /*
Neale Ranns89541992017-04-06 04:41:02 -07009909 * cleanup
9910 */
Neale Ranns89541992017-04-06 04:41:02 -07009911 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
Neale Ranns2303cb12018-02-21 04:57:17 -08009912 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_API);
Neale Ranns89541992017-04-06 04:41:02 -07009913 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9914 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9915 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9916 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
Neale Ranns2303cb12018-02-21 04:57:17 -08009917 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_SPECIAL);
Neale Ranns89541992017-04-06 04:41:02 -07009918 adj_unlock(ai_10_10_10_1);
9919 adj_unlock(ai_10_10_10_2);
Neale Ranns2303cb12018-02-21 04:57:17 -08009920 adj_unlock(ai_10_10_10_3);
9921 dpo_reset(&interposer);
9922 dpo_reset(&interposer2);
9923 FIB_TEST(0 == pool_elts(mpls_label_dpo_pool),
9924 "MPLS label pool empty: %d",
9925 pool_elts(mpls_label_dpo_pool));
9926 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9927 FIB_TEST(N_PLS == fib_path_list_pool_size(),
9928 "number of path-lists: %d = %d",
9929 N_PLS, fib_path_list_pool_size());
Neale Ranns89541992017-04-06 04:41:02 -07009930
9931 /*
9932 * test the v6 tree walk.
Neale Ranns2303cb12018-02-21 04:57:17 -08009933 * a /64 that covers everything. a /96 that covers one /128
Neale Ranns89541992017-04-06 04:41:02 -07009934 * a second /128 covered only by the /64.
9935 */
9936 const fib_prefix_t pfx_2001_s_64 = {
9937 .fp_len = 64,
9938 .fp_proto = FIB_PROTOCOL_IP6,
9939 .fp_addr = {
9940 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009941 .as_u64 = {
9942 [0] = clib_host_to_net_u64(0x2001000000000000),
9943 [1] = clib_host_to_net_u64(0x0000000000000000),
9944 },
Neale Ranns89541992017-04-06 04:41:02 -07009945 },
9946 },
9947 };
9948 const fib_prefix_t pfx_2001_1_s_96 = {
9949 .fp_len = 96,
9950 .fp_proto = FIB_PROTOCOL_IP6,
9951 .fp_addr = {
9952 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009953 .as_u64 = {
9954 [0] = clib_host_to_net_u64(0x2001000000000000),
9955 [1] = clib_host_to_net_u64(0x1000000000000000),
9956 },
Neale Ranns89541992017-04-06 04:41:02 -07009957 },
9958 },
9959 };
9960 const fib_prefix_t pfx_2001_1_1_s_128 = {
9961 .fp_len = 128,
9962 .fp_proto = FIB_PROTOCOL_IP6,
9963 .fp_addr = {
9964 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009965 .as_u64 = {
9966 [0] = clib_host_to_net_u64(0x2001000000000000),
9967 [1] = clib_host_to_net_u64(0x1000000000000001),
9968 },
Neale Ranns89541992017-04-06 04:41:02 -07009969 },
9970 },
9971 };
9972 const fib_prefix_t pfx_2001_0_1_s_128 = {
9973 .fp_len = 128,
9974 .fp_proto = FIB_PROTOCOL_IP6,
9975 .fp_addr = {
9976 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009977 .as_u64 = {
9978 [0] = clib_host_to_net_u64(0x2001000000000000),
9979 [1] = clib_host_to_net_u64(0x0000000000000001),
9980 },
Neale Ranns89541992017-04-06 04:41:02 -07009981 },
9982 },
9983 };
9984 const ip46_address_t nh_3000_1 = {
9985 .ip6 = {
9986 .as_u64 = {
9987 [0] = clib_host_to_net_u64(0x3000000000000000),
9988 [1] = clib_host_to_net_u64(0x0000000000000001),
9989 },
9990 },
9991 };
9992 const ip46_address_t nh_3000_2 = {
9993 .ip6 = {
9994 .as_u64 = {
9995 [0] = clib_host_to_net_u64(0x3000000000000000),
9996 [1] = clib_host_to_net_u64(0x0000000000000002),
9997 },
9998 },
9999 };
10000 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
10001 VNET_LINK_IP6,
10002 &nh_3000_1,
10003 tm->hw[0]->sw_if_index);
10004 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
10005 VNET_LINK_IP6,
10006 &nh_3000_2,
10007 tm->hw[0]->sw_if_index);
10008 fib_test_lb_bucket_t adj_o_3000_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010009 .type = FT_LB_ADJ,
10010 .adj = {
10011 .adj = ai_3000_1,
10012 },
Neale Ranns89541992017-04-06 04:41:02 -070010013 };
10014 fib_test_lb_bucket_t adj_o_3000_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010015 .type = FT_LB_ADJ,
10016 .adj = {
10017 .adj = ai_3000_2,
10018 },
Neale Ranns89541992017-04-06 04:41:02 -070010019 };
10020
10021 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010022 &pfx_2001_0_1_s_128,
10023 FIB_SOURCE_CLI,
10024 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010025 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010026 &pfx_2001_1_1_s_128,
10027 FIB_SOURCE_CLI,
10028 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010029
10030 /*
10031 * /96 has inherited forwarding pushed down to its covered /128
10032 */
10033 fib_table_entry_update_one_path(0,
10034 &pfx_2001_1_s_96,
Neale Ranns2303cb12018-02-21 04:57:17 -080010035 FIB_SOURCE_API,
10036 FIB_ENTRY_FLAG_COVERED_INHERIT,
10037 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010038 &nh_3000_1,
Neale Ranns2303cb12018-02-21 04:57:17 -080010039 tm->hw[0]->sw_if_index,
10040 ~0,
10041 1,
10042 NULL,
10043 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010044 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
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_s_96);
10051 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010052 FIB_TEST(!fib_test_validate_entry(fei,
10053 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10054 1,
10055 &adj_o_3000_1),
10056 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010057 format_fib_prefix, &pfx_2001_1_1_s_128);
10058 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
10059 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
10060 "%U resolves via drop",
10061 format_fib_prefix, &pfx_2001_0_1_s_128);
10062
10063 /*
10064 * /64 has inherited forwarding pushed down to all, but the /96
10065 * and its sub-tree remain unaffected.
10066 */
10067 fib_table_entry_update_one_path(0,
10068 &pfx_2001_s_64,
Neale Ranns2303cb12018-02-21 04:57:17 -080010069 FIB_SOURCE_API,
10070 FIB_ENTRY_FLAG_COVERED_INHERIT,
10071 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010072 &nh_3000_2,
Neale Ranns2303cb12018-02-21 04:57:17 -080010073 tm->hw[0]->sw_if_index,
10074 ~0,
10075 1,
10076 NULL,
10077 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010078
10079 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
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::2",
Neale Ranns89541992017-04-06 04:41:02 -070010085 format_fib_prefix, &pfx_2001_s_64);
10086 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010087 FIB_TEST(!fib_test_validate_entry(fei,
10088 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10089 1,
10090 &adj_o_3000_2),
10091 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010092 format_fib_prefix, &pfx_2001_0_1_s_128);
10093
10094 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
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_s_96);
10101 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010102 FIB_TEST(!fib_test_validate_entry(fei,
10103 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10104 1,
10105 &adj_o_3000_1),
10106 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010107 format_fib_prefix, &pfx_2001_1_1_s_128);
10108
10109 /*
10110 * Cleanup
10111 */
10112 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
10113 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
10114 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
10115 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
10116 adj_unlock(ai_3000_1);
10117 adj_unlock(ai_3000_2);
10118
10119 /*
10120 * test no-one left behind
10121 */
10122 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
10123 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -080010124
10125 return (res);
Neale Ranns89541992017-04-06 04:41:02 -070010126}
10127
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010128static clib_error_t *
Neale Ranns2303cb12018-02-21 04:57:17 -080010129fib_test (vlib_main_t * vm,
10130 unformat_input_t * input,
10131 vlib_cli_command_t * cmd_arg)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010132{
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010133 int res;
10134
10135 res = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -080010136
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010137 fib_test_mk_intf(4);
10138
Neale Ranns88fc83e2017-04-05 08:11:14 -070010139 if (unformat (input, "debug"))
10140 {
10141 fib_test_do_debug = 1;
10142 }
10143
Neale Ranns2303cb12018-02-21 04:57:17 -080010144 if (unformat (input, "ip4"))
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010145 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010146 res += fib_test_v4();
10147 }
10148 else if (unformat (input, "ip6"))
10149 {
10150 res += fib_test_v6();
10151 }
10152 else if (unformat (input, "ip"))
10153 {
10154 res += fib_test_v4();
10155 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010156 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010157 else if (unformat (input, "label"))
10158 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010159 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010160 }
10161 else if (unformat (input, "ae"))
10162 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010163 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010164 }
Neale Ranns57b58602017-07-15 07:37:25 -070010165 else if (unformat (input, "pref"))
10166 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010167 res += fib_test_pref();
Neale Ranns57b58602017-07-15 07:37:25 -070010168 }
Neale Rannsad422ed2016-11-02 14:20:04 +000010169 else if (unformat (input, "lfib"))
10170 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010171 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +000010172 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010173 else if (unformat (input, "walk"))
10174 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010175 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010176 }
Neale Ranns88fc83e2017-04-05 08:11:14 -070010177 else if (unformat (input, "bfd"))
10178 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010179 res += fib_test_bfd();
Neale Ranns88fc83e2017-04-05 08:11:14 -070010180 }
Neale Ranns89541992017-04-06 04:41:02 -070010181 else if (unformat (input, "inherit"))
10182 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010183 res += fib_test_inherit();
Neale Ranns89541992017-04-06 04:41:02 -070010184 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010185 else
10186 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010187 res += fib_test_v4();
10188 res += fib_test_v6();
10189 res += fib_test_ae();
10190 res += fib_test_bfd();
10191 res += fib_test_pref();
10192 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -070010193 res += fib_test_inherit();
Neale Ranns2303cb12018-02-21 04:57:17 -080010194 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -070010195
10196 /*
10197 * fib-walk process must be disabled in order for the walk tests to work
10198 */
10199 fib_walk_process_disable();
10200 res += fib_test_walk();
10201 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010202 }
10203
Neale Ranns2303cb12018-02-21 04:57:17 -080010204 fflush(NULL);
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010205 if (res)
10206 {
10207 return clib_error_return(0, "FIB Unit Test Failed");
10208 }
10209 else
10210 {
10211 return (NULL);
10212 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010213}
10214
10215VLIB_CLI_COMMAND (test_fib_command, static) = {
10216 .path = "test fib",
10217 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
10218 .function = fib_test,
10219};
10220
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010221clib_error_t *
10222fib_test_init (vlib_main_t *vm)
10223{
10224 return 0;
10225}
10226
10227VLIB_INIT_FUNCTION (fib_test_init);