blob: e26cc674a88be3b77f2cf554989d119f6adc7310 [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)) { \
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700215 res = 1; \
216 goto cleanup; \
Neale Ranns2303cb12018-02-21 04:57:17 -0800217 } \
218 }
Neale Ranns3ee44042016-10-03 13:05:48 +0100219
220static int
221fib_test_urpf_is_equal (fib_node_index_t fei,
Neale Ranns2303cb12018-02-21 04:57:17 -0800222 fib_forward_chain_type_t fct,
223 u32 num, ...)
Neale Ranns3ee44042016-10-03 13:05:48 +0100224{
Neale Ranns948e00f2016-10-20 13:39:34 +0100225 dpo_id_t dpo = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +0100226 fib_urpf_list_t *urpf;
Neale Ranns2303cb12018-02-21 04:57:17 -0800227 int ii, res;
Neale Ranns3ee44042016-10-03 13:05:48 +0100228 index_t ui;
229 va_list ap;
Neale Ranns3ee44042016-10-03 13:05:48 +0100230
231 va_start(ap, num);
232
Neale Ranns2303cb12018-02-21 04:57:17 -0800233 res = 0;
Neale Ranns3ee44042016-10-03 13:05:48 +0100234 fib_entry_contribute_forwarding(fei, fct, &dpo);
235 ui = load_balance_get_urpf(dpo.dpoi_index);
236
237 urpf = fib_urpf_list_get(ui);
238
239 FIB_TEST_RPF(num == vec_len(urpf->furpf_itfs),
Neale Ranns2303cb12018-02-21 04:57:17 -0800240 "RPF:%U len %d == %d",
241 format_fib_urpf_list, ui,
242 num, vec_len(urpf->furpf_itfs));
Neale Ranns3ee44042016-10-03 13:05:48 +0100243 FIB_TEST_RPF(num == fib_urpf_check_size(ui),
Neale Ranns2303cb12018-02-21 04:57:17 -0800244 "RPF:%U check-size %d == %d",
245 format_fib_urpf_list, ui,
246 num, vec_len(urpf->furpf_itfs));
Neale Ranns3ee44042016-10-03 13:05:48 +0100247
248 for (ii = 0; ii < num; ii++)
249 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800250 adj_index_t ai = va_arg(ap, adj_index_t);
Neale Ranns3ee44042016-10-03 13:05:48 +0100251
Neale Ranns2303cb12018-02-21 04:57:17 -0800252 FIB_TEST_RPF(ai == urpf->furpf_itfs[ii],
253 "RPF:%d item:%d - %d == %d",
254 ui, ii, ai, urpf->furpf_itfs[ii]);
255 FIB_TEST_RPF(fib_urpf_check(ui, ai),
256 "RPF:%d %d found",
257 ui, ai);
Neale Ranns3ee44042016-10-03 13:05:48 +0100258 }
259
260 dpo_reset(&dpo);
261
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700262cleanup:
Neale Ranns5899fde2016-10-12 13:51:05 +0100263 va_end(ap);
264
Neale Ranns2303cb12018-02-21 04:57:17 -0800265 return (res);
Neale Ranns3ee44042016-10-03 13:05:48 +0100266}
267
Neale Rannsb80c5362016-10-08 13:03:40 +0100268static u8*
269fib_test_build_rewrite (u8 *eth_addr)
270{
271 u8* rewrite = NULL;
272
273 vec_validate(rewrite, 13);
274
275 memcpy(rewrite, eth_addr, 6);
276 memcpy(rewrite+6, eth_addr, 6);
277
278 return (rewrite);
279}
280
Neale Ranns2303cb12018-02-21 04:57:17 -0800281#define FIB_TEST_LB(_cond, _comment, _args...) \
282 { \
283 if (FIB_TEST_I(_cond, _comment, ##_args)) { \
284 return (1); \
285 } \
286 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000287
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800288int
289fib_test_validate_rep_v (const replicate_t *rep,
290 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200291 va_list *ap)
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800292{
293 const fib_test_rep_bucket_t *exp;
294 const dpo_id_t *dpo;
Neale Ranns2303cb12018-02-21 04:57:17 -0800295 int bucket, res;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800296
Neale Ranns2303cb12018-02-21 04:57:17 -0800297 res = 0;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800298 FIB_TEST_LB((n_buckets == rep->rep_n_buckets),
299 "n_buckets = %d", rep->rep_n_buckets);
300
301 for (bucket = 0; bucket < n_buckets; bucket++)
302 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800303 exp = va_arg(*ap, fib_test_rep_bucket_t*);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800304
305 dpo = replicate_get_bucket_i(rep, bucket);
306
Neale Ranns2303cb12018-02-21 04:57:17 -0800307 switch (exp->type)
308 {
309 case FT_REP_LABEL_O_ADJ:
310 {
311 const mpls_label_dpo_t *mld;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800312 mpls_label_t hdr;
Neale Ranns2303cb12018-02-21 04:57:17 -0800313
Neale Ranns31ed7442018-02-23 05:29:09 -0800314 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
315 == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800316 "bucket %d stacks on %U",
317 bucket,
318 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800319
320 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800321 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
322
Neale Ranns2303cb12018-02-21 04:57:17 -0800323 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
324 exp->label_o_adj.label),
325 "bucket %d stacks on label %d",
326 bucket,
327 exp->label_o_adj.label);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800328
Neale Ranns2303cb12018-02-21 04:57:17 -0800329 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
330 exp->label_o_adj.eos),
331 "bucket %d stacks on label %d %U",
332 bucket,
333 exp->label_o_adj.label,
334 format_mpls_eos_bit, exp->label_o_adj.eos);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800335
Neale Ranns2303cb12018-02-21 04:57:17 -0800336 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
337 "bucket %d label stacks on %U",
338 bucket,
339 format_dpo_type, mld->mld_dpo.dpoi_type);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800340
Neale Ranns2303cb12018-02-21 04:57:17 -0800341 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
342 "bucket %d label stacks on adj %d",
343 bucket,
344 exp->label_o_adj.adj);
345 }
346 break;
347 case FT_REP_INTF:
Neale Ranns43161a82017-08-12 02:12:00 -0700348 FIB_TEST_LB((DPO_INTERFACE_RX == dpo->dpoi_type),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800349 "bucket %d stacks on %U",
350 bucket,
351 format_dpo_type, dpo->dpoi_type);
352
353 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
354 "bucket %d stacks on adj %d",
355 bucket,
356 exp->adj.adj);
Neale Ranns2303cb12018-02-21 04:57:17 -0800357 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800358 case FT_REP_DISP_MFIB_LOOKUP:
359// ASSERT(0);
360 break;
361 }
362 }
363
Neale Ranns2303cb12018-02-21 04:57:17 -0800364 return (res);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800365}
366
367int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000368fib_test_validate_lb_v (const load_balance_t *lb,
Neale Ranns2303cb12018-02-21 04:57:17 -0800369 int n_buckets,
370 va_list *ap)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000371{
372 const dpo_id_t *dpo;
Neale Ranns2303cb12018-02-21 04:57:17 -0800373 int bucket, res;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000374
Neale Ranns2303cb12018-02-21 04:57:17 -0800375 res = 0;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000376 FIB_TEST_LB((n_buckets == lb->lb_n_buckets), "n_buckets = %d", lb->lb_n_buckets);
377
378 for (bucket = 0; bucket < n_buckets; bucket++)
379 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800380 const fib_test_lb_bucket_t *exp;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000381
Neale Ranns2303cb12018-02-21 04:57:17 -0800382 exp = va_arg(*ap, fib_test_lb_bucket_t*);
383 dpo = load_balance_get_bucket_i(lb, bucket);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000384
385 switch (exp->type)
386 {
Neale Rannsad422ed2016-11-02 14:20:04 +0000387 case FT_LB_LABEL_STACK_O_ADJ:
388 {
389 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800390 mpls_label_dpo_flags_t mf;
Neale Rannsad422ed2016-11-02 14:20:04 +0000391 mpls_label_t hdr;
392 u32 ii;
393
Neale Ranns31ed7442018-02-23 05:29:09 -0800394 mf = ((exp->label_stack_o_adj.mode ==
395 FIB_MPLS_LSP_MODE_UNIFORM) ?
396 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
397 MPLS_LABEL_DPO_FLAG_NONE);
398 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Rannsad422ed2016-11-02 14:20:04 +0000399 "bucket %d stacks on %U",
400 bucket,
401 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800402
Neale Rannsad422ed2016-11-02 14:20:04 +0000403 mld = mpls_label_dpo_get(dpo->dpoi_index);
404
405 FIB_TEST_LB(exp->label_stack_o_adj.label_stack_size == mld->mld_n_labels,
406 "label stack size",
407 mld->mld_n_labels);
408
409 for (ii = 0; ii < mld->mld_n_labels; ii++)
410 {
411 hdr = clib_net_to_host_u32(mld->mld_hdr[ii].label_exp_s_ttl);
412 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
413 exp->label_stack_o_adj.label_stack[ii]),
414 "bucket %d stacks on label %d",
415 bucket,
416 exp->label_stack_o_adj.label_stack[ii]);
417
418 if (ii == mld->mld_n_labels-1)
419 {
420 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
421 exp->label_o_adj.eos),
422 "bucket %d stacks on label %d %U!=%U",
423 bucket,
424 exp->label_stack_o_adj.label_stack[ii],
425 format_mpls_eos_bit, exp->label_o_adj.eos,
426 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
427 }
428 else
429 {
430 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) == MPLS_NON_EOS),
431 "bucket %d stacks on label %d %U",
432 bucket,
433 exp->label_stack_o_adj.label_stack[ii],
434 format_mpls_eos_bit, vnet_mpls_uc_get_s(hdr));
435 }
436 }
437
438 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
439 "bucket %d label stacks on %U",
440 bucket,
441 format_dpo_type, mld->mld_dpo.dpoi_type);
442
443 FIB_TEST_LB((exp->label_stack_o_adj.adj == mld->mld_dpo.dpoi_index),
444 "bucket %d label stacks on adj %d",
445 bucket,
446 exp->label_stack_o_adj.adj);
447 }
448 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000449 case FT_LB_LABEL_O_ADJ:
450 {
451 const mpls_label_dpo_t *mld;
452 mpls_label_t hdr;
Neale Ranns31ed7442018-02-23 05:29:09 -0800453 FIB_TEST_LB((mpls_label_dpo_get_type(MPLS_LABEL_DPO_FLAG_NONE)
454 == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000455 "bucket %d stacks on %U",
456 bucket,
457 format_dpo_type, dpo->dpoi_type);
458
459 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000460 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000461
462 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
463 exp->label_o_adj.label),
464 "bucket %d stacks on label %d",
465 bucket,
466 exp->label_o_adj.label);
467
468 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
469 exp->label_o_adj.eos),
470 "bucket %d stacks on label %d %U",
471 bucket,
472 exp->label_o_adj.label,
473 format_mpls_eos_bit, exp->label_o_adj.eos);
474
475 FIB_TEST_LB((DPO_ADJACENCY_INCOMPLETE == mld->mld_dpo.dpoi_type),
476 "bucket %d label stacks on %U",
477 bucket,
478 format_dpo_type, mld->mld_dpo.dpoi_type);
479
480 FIB_TEST_LB((exp->label_o_adj.adj == mld->mld_dpo.dpoi_index),
481 "bucket %d label stacks on adj %d",
482 bucket,
483 exp->label_o_adj.adj);
484 }
485 break;
486 case FT_LB_LABEL_O_LB:
487 {
488 const mpls_label_dpo_t *mld;
Neale Ranns31ed7442018-02-23 05:29:09 -0800489 mpls_label_dpo_flags_t mf;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000490 mpls_label_t hdr;
491
Neale Ranns31ed7442018-02-23 05:29:09 -0800492 mf = ((exp->label_o_lb.mode ==
493 FIB_MPLS_LSP_MODE_UNIFORM) ?
494 MPLS_LABEL_DPO_FLAG_UNIFORM_MODE :
495 MPLS_LABEL_DPO_FLAG_NONE);
496 FIB_TEST_LB((mpls_label_dpo_get_type(mf) == dpo->dpoi_type),
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000497 "bucket %d stacks on %U",
498 bucket,
499 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800500
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000501 mld = mpls_label_dpo_get(dpo->dpoi_index);
Neale Rannsad422ed2016-11-02 14:20:04 +0000502 hdr = clib_net_to_host_u32(mld->mld_hdr[0].label_exp_s_ttl);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000503
Neale Rannsad422ed2016-11-02 14:20:04 +0000504 FIB_TEST_LB(1 == mld->mld_n_labels, "label stack size",
505 mld->mld_n_labels);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000506 FIB_TEST_LB((vnet_mpls_uc_get_label(hdr) ==
507 exp->label_o_lb.label),
508 "bucket %d stacks on label %d",
509 bucket,
510 exp->label_o_lb.label);
511
512 FIB_TEST_LB((vnet_mpls_uc_get_s(hdr) ==
513 exp->label_o_lb.eos),
514 "bucket %d stacks on label %d %U",
515 bucket,
516 exp->label_o_lb.label,
517 format_mpls_eos_bit, exp->label_o_lb.eos);
518
519 FIB_TEST_LB((DPO_LOAD_BALANCE == mld->mld_dpo.dpoi_type),
520 "bucket %d label stacks on %U",
521 bucket,
522 format_dpo_type, mld->mld_dpo.dpoi_type);
523
524 FIB_TEST_LB((exp->label_o_lb.lb == mld->mld_dpo.dpoi_index),
525 "bucket %d label stacks on LB %d",
526 bucket,
527 exp->label_o_lb.lb);
528 }
529 break;
530 case FT_LB_ADJ:
Neale Ranns756cd942018-04-06 09:18:11 -0700531 res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
532 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
533 "bucket %d stacks on %U",
534 bucket,
535 format_dpo_type, dpo->dpoi_type);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000536 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
537 "bucket %d stacks on adj %d",
538 bucket,
539 exp->adj.adj);
540 break;
Neale Ranns31ed7442018-02-23 05:29:09 -0800541 case FT_LB_MPLS_DISP_PIPE_O_ADJ:
Neale Ranns62fe07c2017-10-31 12:28:22 -0700542 {
543 const mpls_disp_dpo_t *mdd;
544
Neale Ranns756cd942018-04-06 09:18:11 -0700545 res = FIB_TEST_I((DPO_MPLS_DISPOSITION_PIPE == dpo->dpoi_type),
Neale Ranns62fe07c2017-10-31 12:28:22 -0700546 "bucket %d stacks on %U",
547 bucket,
548 format_dpo_type, dpo->dpoi_type);
Neale Ranns31ed7442018-02-23 05:29:09 -0800549
Neale Ranns62fe07c2017-10-31 12:28:22 -0700550 mdd = mpls_disp_dpo_get(dpo->dpoi_index);
551
552 dpo = &mdd->mdd_dpo;
553
Neale Ranns756cd942018-04-06 09:18:11 -0700554 res = FIB_TEST_I(((DPO_ADJACENCY == dpo->dpoi_type) ||
555 (DPO_ADJACENCY_INCOMPLETE == dpo->dpoi_type)),
556 "bucket %d stacks on %U",
557 bucket,
558 format_dpo_type, dpo->dpoi_type);
Neale Ranns62fe07c2017-10-31 12:28:22 -0700559 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
560 "bucket %d stacks on adj %d",
561 bucket,
562 exp->adj.adj);
563 break;
564 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800565 case FT_LB_INTF:
Neale Ranns756cd942018-04-06 09:18:11 -0700566 res = FIB_TEST_I((DPO_INTERFACE_RX == dpo->dpoi_type),
567 "bucket %d stacks on %U",
568 bucket,
569 format_dpo_type, dpo->dpoi_type);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800570 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
571 "bucket %d stacks on adj %d",
572 bucket,
573 exp->adj.adj);
574 break;
Neale Ranns6f631152017-10-03 08:20:21 -0700575 case FT_LB_L2:
Neale Ranns756cd942018-04-06 09:18:11 -0700576 res = FIB_TEST_I((DPO_DVR == dpo->dpoi_type),
577 "bucket %d stacks on %U",
578 bucket,
579 format_dpo_type, dpo->dpoi_type);
Neale Ranns6f631152017-10-03 08:20:21 -0700580 FIB_TEST_LB((exp->adj.adj == dpo->dpoi_index),
581 "bucket %d stacks on adj %d",
582 bucket,
583 exp->adj.adj);
584 break;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000585 case FT_LB_O_LB:
Neale Ranns756cd942018-04-06 09:18:11 -0700586 res = FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
587 "bucket %d stacks on %U",
588 bucket,
589 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800590 FIB_TEST_LB((exp->lb.lb == dpo->dpoi_index),
591 "bucket %d stacks on lb %d not %d",
592 bucket,
593 dpo->dpoi_index,
Neale Ranns57b58602017-07-15 07:37:25 -0700594 exp->lb.lb);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700595 break;
Neale Ranns2303cb12018-02-21 04:57:17 -0800596 case FT_LB_BIER_TABLE:
597 FIB_TEST_LB((DPO_BIER_TABLE == dpo->dpoi_type),
Neale Rannsd792d9c2017-10-21 10:53:20 -0700598 "bucket %d stacks on %U",
599 bucket,
600 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800601 FIB_TEST_LB((exp->bier.table == dpo->dpoi_index),
602 "bucket %d stacks on lb %d",
603 bucket,
604 exp->bier.table);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700605 break;
Neale Ranns2303cb12018-02-21 04:57:17 -0800606 case FT_LB_BIER_FMASK:
607 FIB_TEST_LB((DPO_BIER_FMASK == dpo->dpoi_type),
Neale Rannsd792d9c2017-10-21 10:53:20 -0700608 "bucket %d stacks on %U",
609 bucket,
610 format_dpo_type, dpo->dpoi_type);
Neale Ranns2303cb12018-02-21 04:57:17 -0800611 FIB_TEST_LB((exp->bier.fmask == dpo->dpoi_index),
612 "bucket %d stacks on lb %d",
613 bucket,
614 exp->bier.fmask);
615 break;
616 case FT_LB_DROP:
617 FIB_TEST_LB((DPO_DROP == dpo->dpoi_type),
618 "bucket %d stacks on %U",
619 bucket,
620 format_dpo_type, dpo->dpoi_type);
621 break;
622 case FT_LB_PUNT:
623 FIB_TEST_LB((DPO_PUNT == dpo->dpoi_type),
624 "bucket %d stacks on %U",
625 bucket,
626 format_dpo_type, dpo->dpoi_type);
627 break;
628 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000629 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800630 return (res);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000631}
632
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800633int
Neale Rannsd792d9c2017-10-21 10:53:20 -0700634fib_test_validate_lb (const dpo_id_t *dpo,
Neale Ranns2303cb12018-02-21 04:57:17 -0800635 int n_buckets,
636 ...)
Neale Rannsd792d9c2017-10-21 10:53:20 -0700637{
638 const load_balance_t *lb;
639 va_list ap;
640 int res;
641
Neale Ranns2303cb12018-02-21 04:57:17 -0800642 res = 0;
Neale Rannsd792d9c2017-10-21 10:53:20 -0700643 va_start(ap, n_buckets);
644
Neale Rannsac64b712018-10-08 14:51:11 +0000645 if (!FIB_TEST_I((DPO_LOAD_BALANCE == dpo->dpoi_type),
646 "Entry links to %U",
647 format_dpo_type, dpo->dpoi_type))
Neale Ranns93149bb2017-11-15 10:44:07 -0800648 {
649 lb = load_balance_get(dpo->dpoi_index);
Neale Rannsd792d9c2017-10-21 10:53:20 -0700650
Neale Ranns93149bb2017-11-15 10:44:07 -0800651 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
652 }
653 else
654 {
Neale Rannsac64b712018-10-08 14:51:11 +0000655 res = 1;
Neale Ranns93149bb2017-11-15 10:44:07 -0800656 }
Neale Rannsd792d9c2017-10-21 10:53:20 -0700657
658 va_end(ap);
659
660 return (res);
661}
662
663int
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000664fib_test_validate_entry (fib_node_index_t fei,
Neale Ranns2303cb12018-02-21 04:57:17 -0800665 fib_forward_chain_type_t fct,
666 int n_buckets,
667 ...)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000668{
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000669 dpo_id_t dpo = DPO_INVALID;
Neale Rannsc5d43172018-07-30 08:04:40 -0700670 const fib_prefix_t *pfx;
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000671 index_t fw_lbi;
672 u32 fib_index;
673 va_list ap;
674 int res;
675
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000676
Neale Ranns2303cb12018-02-21 04:57:17 -0800677 res = 0;
Neale Rannsc5d43172018-07-30 08:04:40 -0700678 pfx = fib_entry_get_prefix(fei);
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000679 fib_index = fib_entry_get_fib_index(fei);
680 fib_entry_contribute_forwarding(fei, fct, &dpo);
681
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800682 if (DPO_REPLICATE == dpo.dpoi_type)
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000683 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800684 const replicate_t *rep;
685
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700686 va_start(ap, n_buckets);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800687 rep = replicate_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200688 res = fib_test_validate_rep_v(rep, n_buckets, &ap);
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700689 va_end (ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800690 }
691 else
692 {
693 const load_balance_t *lb;
694
695 FIB_TEST_LB((DPO_LOAD_BALANCE == dpo.dpoi_type),
Neale Ranns89541992017-04-06 04:41:02 -0700696 "%U Entry links to %U",
Neale Rannsc5d43172018-07-30 08:04:40 -0700697 format_fib_prefix, pfx,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800698 format_dpo_type, dpo.dpoi_type);
699
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700700 va_start(ap, n_buckets);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800701 lb = load_balance_get(dpo.dpoi_index);
Christophe Fontained3c008d2017-10-02 18:10:54 +0200702 res = fib_test_validate_lb_v(lb, n_buckets, &ap);
Paul Vinciguerra0c0383d2018-10-24 12:14:09 -0700703 va_end(ap);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800704
705 /*
706 * ensure that the LB contributed by the entry is the
707 * same as the LB in the forwarding tables
708 */
709 if (fct == fib_entry_get_default_chain_type(fib_entry_get(fei)))
Neale Rannsad422ed2016-11-02 14:20:04 +0000710 {
Neale Rannsc5d43172018-07-30 08:04:40 -0700711 switch (pfx->fp_proto)
Neale Rannsad422ed2016-11-02 14:20:04 +0000712 {
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800713 case FIB_PROTOCOL_IP4:
Neale Rannsc5d43172018-07-30 08:04:40 -0700714 fw_lbi = ip4_fib_forwarding_lookup(fib_index, &pfx->fp_addr.ip4);
Neale Rannsad422ed2016-11-02 14:20:04 +0000715 break;
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800716 case FIB_PROTOCOL_IP6:
Neale Rannsc5d43172018-07-30 08:04:40 -0700717 fw_lbi = ip6_fib_table_fwding_lookup(&ip6_main, fib_index, &pfx->fp_addr.ip6);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800718 break;
719 case FIB_PROTOCOL_MPLS:
720 {
721 mpls_unicast_header_t hdr = {
722 .label_exp_s_ttl = 0,
723 };
724
Neale Rannsc5d43172018-07-30 08:04:40 -0700725 vnet_mpls_uc_set_label(&hdr.label_exp_s_ttl, pfx->fp_label);
726 vnet_mpls_uc_set_s(&hdr.label_exp_s_ttl, pfx->fp_eos);
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800727 hdr.label_exp_s_ttl = clib_host_to_net_u32(hdr.label_exp_s_ttl);
728
729 fw_lbi = mpls_fib_table_forwarding_lookup(fib_index, &hdr);
730 break;
731 }
732 default:
733 fw_lbi = 0;
Neale Rannsad422ed2016-11-02 14:20:04 +0000734 }
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800735 FIB_TEST_LB((fw_lbi == dpo.dpoi_index),
Neale Ranns89541992017-04-06 04:41:02 -0700736 "Contributed LB = FW LB:\n fwd:%U\n cont:%U",
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800737 format_load_balance, fw_lbi, 0,
738 format_load_balance, dpo.dpoi_index, 0);
Neale Rannsad422ed2016-11-02 14:20:04 +0000739 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000740 }
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000741
742 dpo_reset(&dpo);
743
Neale Ranns0bd36ea2016-11-16 11:47:44 +0000744 return (res);
745}
746
Neale Ranns0ebe8d72016-12-08 19:48:11 +0000747static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100748fib_test_v4 (void)
749{
750 /*
751 * In the default table check for the presence and correct forwarding
752 * of the special entries
753 */
754 fib_node_index_t dfrt, fei, ai, ai2, locked_ai, ai_01, ai_02, ai_03;
755 const dpo_id_t *dpo, *dpo1, *dpo2, *dpo_drop;
756 const ip_adjacency_t *adj;
757 const load_balance_t *lb;
758 test_main_t *tm;
759 u32 fib_index;
Neale Ranns994dab42017-04-18 12:56:45 -0700760 int lb_count;
Neale Ranns2303cb12018-02-21 04:57:17 -0800761 int ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100762
Neale Ranns2303cb12018-02-21 04:57:17 -0800763 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100764 /* via 10.10.10.1 */
765 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800766 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100767 };
768 /* via 10.10.10.2 */
769 ip46_address_t nh_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800770 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100771 };
772
Neale Rannsf12a83f2017-04-18 09:09:40 -0700773 FIB_TEST((0 == pool_elts(load_balance_map_pool)), "LB-map pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -0800774 pool_elts(load_balance_map_pool));
Neale Rannsf12a83f2017-04-18 09:09:40 -0700775
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100776 tm = &test_main;
777
Neale Ranns994dab42017-04-18 12:56:45 -0700778 /* record the nubmer of load-balances in use before we start */
779 lb_count = pool_elts(load_balance_pool);
780
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100781 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700782 fib_index = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 11,
783 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100784
785 for (ii = 0; ii < 4; ii++)
786 {
Neale Ranns2303cb12018-02-21 04:57:17 -0800787 ip4_main.fib_index_by_sw_if_index[tm->hw[ii]->sw_if_index] = fib_index;
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100788 }
789
790 fib_prefix_t pfx_0_0_0_0_s_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800791 .fp_len = 0,
792 .fp_proto = FIB_PROTOCOL_IP4,
793 .fp_addr = {
794 .ip4 = {
795 {0}
796 },
797 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100798 };
799
800 fib_prefix_t pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -0800801 .fp_len = 0,
802 .fp_proto = FIB_PROTOCOL_IP4,
803 .fp_addr = {
804 .ip4 = {
805 {0}
806 },
807 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100808 };
809
810 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
811
812 dfrt = fib_table_lookup(fib_index, &pfx_0_0_0_0_s_0);
813 FIB_TEST((FIB_NODE_INDEX_INVALID != dfrt), "default route present");
814 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800815 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100816
817 pfx.fp_len = 32;
818 fei = fib_table_lookup(fib_index, &pfx);
819 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all zeros route present");
820 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800821 "all 0s route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100822
823 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xffffffff);
824 pfx.fp_len = 32;
825 fei = fib_table_lookup(fib_index, &pfx);
826 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all ones route present");
827 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800828 "all 1s route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100829
830 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xe0000000);
831 pfx.fp_len = 8;
832 fei = fib_table_lookup(fib_index, &pfx);
833 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "all-mcast route present");
834 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800835 "all-mcast route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100836
837 pfx.fp_addr.ip4.as_u32 = clib_host_to_net_u32(0xf0000000);
838 pfx.fp_len = 8;
839 fei = fib_table_lookup(fib_index, &pfx);
840 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "class-e route present");
841 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -0800842 "class-e route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100843
844 /*
845 * at this stage there are 5 entries in the test FIB (plus 5 in the default),
846 * all of which are special sourced and so none of which share path-lists.
Neale Ranns32e1c012016-11-22 17:07:28 +0000847 * There are also 2 entries, and 2 non-shared path-lists, in the v6 default
848 * table, and 4 path-lists in the v6 MFIB table
Neale Ranns0bfe5d82016-08-25 15:29:12 +0100849 */
Neale Ranns32e1c012016-11-22 17:07:28 +0000850#define ENBR (5+5+2)
Jakub Grajciar7b867a82017-12-08 16:28:42 +0100851
852 u32 PNBR = 5+5+2+4;
853
854 /*
855 * if the IGMP plugin is loaded this adds two more entries to the v4 MFIB
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 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004378 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004379 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004380 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004381 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004382 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004383
4384 /*
4385 * add interface routes.
4386 * validate presence of /64 attached and /128 recieve.
4387 * test for the presence of the receive address in the glean and local adj
4388 *
4389 * receive on 2001:0:0:1::1/128
4390 */
4391 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004392 .fp_len = 64,
4393 .fp_proto = FIB_PROTOCOL_IP6,
4394 .fp_addr = {
4395 .ip6 = {
4396 .as_u64 = {
4397 [0] = clib_host_to_net_u64(0x2001000000000001),
4398 [1] = clib_host_to_net_u64(0x0000000000000001),
4399 },
4400 },
4401 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004402 };
4403
4404 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004405 FIB_SOURCE_INTERFACE,
4406 (FIB_ENTRY_FLAG_CONNECTED |
4407 FIB_ENTRY_FLAG_ATTACHED),
4408 DPO_PROTO_IP6,
4409 NULL,
4410 tm->hw[0]->sw_if_index,
4411 ~0,
4412 1,
4413 NULL,
4414 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004415 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4416
4417 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4418
4419 ai = fib_entry_get_adj(fei);
4420 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "attached interface route adj present");
4421 adj = adj_get(ai);
4422 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004423 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004424 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004425 &adj->sub_type.glean.receive_addr)),
4426 "attached interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004427 dpo = fib_entry_contribute_ip_forwarding(fei);
4428 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004429 &ip6_main,
4430 1,
4431 &local_pfx.fp_addr.ip6)),
4432 "attached-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004433
4434 local_pfx.fp_len = 128;
4435 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004436 FIB_SOURCE_INTERFACE,
4437 (FIB_ENTRY_FLAG_CONNECTED |
4438 FIB_ENTRY_FLAG_LOCAL),
4439 DPO_PROTO_IP6,
4440 NULL,
4441 tm->hw[0]->sw_if_index,
4442 ~0, // invalid fib index
4443 1,
4444 NULL,
4445 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004446 fei = fib_table_lookup(fib_index, &local_pfx);
4447
4448 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4449
4450 dpo = fib_entry_contribute_ip_forwarding(fei);
4451 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4452 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004453 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004454 rd = receive_dpo_get(dpo->dpoi_index);
4455
4456 FIB_TEST((0 == ip46_address_cmp(&local_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004457 &rd->rd_addr)),
4458 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004459
4460 dpo = fib_entry_contribute_ip_forwarding(fei);
4461 FIB_TEST((dpo->dpoi_index == ip6_fib_table_fwding_lookup(
Neale Ranns2303cb12018-02-21 04:57:17 -08004462 &ip6_main,
4463 1,
4464 &local_pfx.fp_addr.ip6)),
4465 "local-route; fwd and non-fwd tables match");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004466
4467 /*
4468 * +2 entries. +2 unshared path-lists
4469 */
4470 FIB_TEST((0 == fib_path_list_db_size()), "path list DB is empty");
Neale Ranns32e1c012016-11-22 17:07:28 +00004471 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004472 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004473 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004474 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004475
4476 /*
4477 * Modify the default route to be via an adj not yet known.
4478 * this sources the defalut route with the API source, which is
4479 * a higher preference to the DEFAULT_ROUTE source
4480 */
4481 fib_table_entry_path_add(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004482 FIB_SOURCE_API,
4483 FIB_ENTRY_FLAG_NONE,
4484 DPO_PROTO_IP6,
4485 &nh_2001_2,
4486 tm->hw[0]->sw_if_index,
4487 ~0,
4488 1,
4489 NULL,
4490 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004491 fei = fib_table_lookup(fib_index, &pfx_0_0);
4492
4493 FIB_TEST((fei == dfrt), "default route same index");
4494 ai = fib_entry_get_adj(fei);
4495 FIB_TEST((FIB_NODE_INDEX_INVALID != ai), "default route adj present");
4496 adj = adj_get(ai);
4497 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004498 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004499 FIB_TEST((0 == ip46_address_cmp(&nh_2001_2, &adj->sub_type.nbr.next_hop)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004500 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004501
4502 /*
4503 * find the adj in the shared db
4504 */
4505 locked_ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004506 VNET_LINK_IP6,
4507 &nh_2001_2,
4508 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004509 FIB_TEST((locked_ai == ai), "ADJ NBR DB find");
4510 adj_unlock(locked_ai);
4511
4512 /*
4513 * no more entires. +1 shared path-list
4514 */
4515 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004516 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004517 FIB_TEST((PNPS+3 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004518 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004519 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004520 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004521
4522 /*
4523 * remove the API source from the default route. We expected
4524 * the route to remain, sourced by DEFAULT_ROUTE, and hence a DROP
4525 */
4526 fib_table_entry_path_remove(fib_index, &pfx_0_0,
Neale Ranns2303cb12018-02-21 04:57:17 -08004527 FIB_SOURCE_API,
4528 DPO_PROTO_IP6,
4529 &nh_2001_2,
4530 tm->hw[0]->sw_if_index,
4531 ~0,
4532 1,
4533 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004534 fei = fib_table_lookup(fib_index, &pfx_0_0);
4535
4536 FIB_TEST((fei == dfrt), "default route same index");
4537 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(dfrt)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004538 "Default route is DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004539
4540 /*
4541 * no more entires. -1 shared path-list
4542 */
4543 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004544 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004545 FIB_TEST((PNPS+2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004546 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004547 FIB_TEST((ENPS+2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004548 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004549
4550 /*
4551 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
4552 */
4553 fib_prefix_t pfx_2001_1_2_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004554 .fp_len = 128,
4555 .fp_proto = FIB_PROTOCOL_IP6,
4556 .fp_addr = {
4557 .ip6 = {
4558 .as_u64 = {
4559 [0] = clib_host_to_net_u64(0x2001000000000001),
4560 [1] = clib_host_to_net_u64(0x0000000000000002),
4561 },
4562 },
4563 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004564 };
4565 fib_prefix_t pfx_2001_1_3_s_128 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004566 .fp_len = 128,
4567 .fp_proto = FIB_PROTOCOL_IP6,
4568 .fp_addr = {
4569 .ip6 = {
4570 .as_u64 = {
4571 [0] = clib_host_to_net_u64(0x2001000000000001),
4572 [1] = clib_host_to_net_u64(0x0000000000000003),
4573 },
4574 },
4575 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004576 };
4577 u8 eth_addr[] = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004578 0xde, 0xde, 0xde, 0xba, 0xba, 0xba,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004579 };
4580
4581 ai_01 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004582 VNET_LINK_IP6,
4583 &pfx_2001_1_2_s_128.fp_addr,
4584 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004585 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_01), "adj created");
4586 adj = adj_get(ai_01);
4587 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004588 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004589 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004590 &adj->sub_type.nbr.next_hop)),
4591 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004592
Neale Rannsb80c5362016-10-08 13:03:40 +01004593 adj_nbr_update_rewrite(ai_01, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004594 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004595 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004596 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004597 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_2_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004598 &adj->sub_type.nbr.next_hop)),
4599 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004600
Neale Ranns81424992017-05-18 03:03:22 -07004601 fib_table_entry_path_add(fib_index,
4602 &pfx_2001_1_2_s_128,
4603 FIB_SOURCE_ADJ,
4604 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004605 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004606 &pfx_2001_1_2_s_128.fp_addr,
4607 tm->hw[0]->sw_if_index,
4608 ~0,
4609 1,
4610 NULL,
4611 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004612
4613 fei = fib_table_lookup(fib_index, &pfx_2001_1_2_s_128);
4614 ai = fib_entry_get_adj(fei);
4615 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4616
4617 eth_addr[5] = 0xb2;
4618
4619 ai_02 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
Neale Ranns2303cb12018-02-21 04:57:17 -08004620 VNET_LINK_IP6,
4621 &pfx_2001_1_3_s_128.fp_addr,
4622 tm->hw[0]->sw_if_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004623 FIB_TEST((FIB_NODE_INDEX_INVALID != ai_02), "adj created");
4624 adj = adj_get(ai_02);
4625 FIB_TEST((IP_LOOKUP_NEXT_ARP == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004626 "adj is incomplete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004627 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004628 &adj->sub_type.nbr.next_hop)),
4629 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004630
Neale Rannsb80c5362016-10-08 13:03:40 +01004631 adj_nbr_update_rewrite(ai_02, ADJ_NBR_REWRITE_FLAG_COMPLETE,
Neale Ranns2303cb12018-02-21 04:57:17 -08004632 fib_test_build_rewrite(eth_addr));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004633 FIB_TEST((IP_LOOKUP_NEXT_REWRITE == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004634 "adj is complete");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004635 FIB_TEST((0 == ip46_address_cmp(&pfx_2001_1_3_s_128.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004636 &adj->sub_type.nbr.next_hop)),
4637 "adj nbr next-hop ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004638 FIB_TEST((ai_01 != ai_02), "ADJs are different");
4639
Neale Ranns81424992017-05-18 03:03:22 -07004640 fib_table_entry_path_add(fib_index,
4641 &pfx_2001_1_3_s_128,
4642 FIB_SOURCE_ADJ,
4643 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07004644 DPO_PROTO_IP6,
Neale Ranns81424992017-05-18 03:03:22 -07004645 &pfx_2001_1_3_s_128.fp_addr,
4646 tm->hw[0]->sw_if_index,
4647 ~0,
4648 1,
4649 NULL,
4650 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004651
4652 fei = fib_table_lookup(fib_index, &pfx_2001_1_3_s_128);
4653 ai = fib_entry_get_adj(fei);
4654 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4655
4656 /*
4657 * +2 entries, +2 unshread path-lists.
4658 */
4659 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004660 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004661 FIB_TEST((PNPS+4 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004662 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004663 FIB_TEST((ENPS+4 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004664 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004665
4666 /*
4667 * Add a 2 routes via the first ADJ. ensure path-list sharing
4668 */
4669 fib_prefix_t pfx_2001_a_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004670 .fp_len = 64,
4671 .fp_proto = FIB_PROTOCOL_IP6,
4672 .fp_addr = {
4673 .ip6 = {
4674 .as_u64 = {
4675 [0] = clib_host_to_net_u64(0x200100000000000a),
4676 [1] = clib_host_to_net_u64(0x0000000000000000),
4677 },
4678 },
4679 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004680 };
4681 fib_prefix_t pfx_2001_b_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004682 .fp_len = 64,
4683 .fp_proto = FIB_PROTOCOL_IP6,
4684 .fp_addr = {
4685 .ip6 = {
4686 .as_u64 = {
4687 [0] = clib_host_to_net_u64(0x200100000000000b),
4688 [1] = clib_host_to_net_u64(0x0000000000000000),
4689 },
4690 },
4691 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004692 };
4693
4694 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004695 &pfx_2001_a_s_64,
4696 FIB_SOURCE_API,
4697 FIB_ENTRY_FLAG_NONE,
4698 DPO_PROTO_IP6,
4699 &nh_2001_2,
4700 tm->hw[0]->sw_if_index,
4701 ~0,
4702 1,
4703 NULL,
4704 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004705 fei = fib_table_lookup(fib_index, &pfx_2001_a_s_64);
4706 ai = fib_entry_get_adj(fei);
4707 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4708 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004709 &pfx_2001_b_s_64,
4710 FIB_SOURCE_API,
4711 FIB_ENTRY_FLAG_NONE,
4712 DPO_PROTO_IP6,
4713 &nh_2001_2,
4714 tm->hw[0]->sw_if_index,
4715 ~0,
4716 1,
4717 NULL,
4718 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004719 fei = fib_table_lookup(fib_index, &pfx_2001_b_s_64);
4720 ai = fib_entry_get_adj(fei);
4721 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4722
4723 /*
4724 * +2 entries, +1 shared path-list.
4725 */
4726 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004727 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004728 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004729 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004730 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004731 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004732
4733 /*
4734 * add a v4 prefix via a v6 next-hop
4735 */
4736 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004737 .fp_len = 32,
4738 .fp_proto = FIB_PROTOCOL_IP4,
4739 .fp_addr = {
4740 .ip4.as_u32 = 0x01010101,
4741 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004742 };
4743 fei = fib_table_entry_path_add(0, // default table
Neale Ranns2303cb12018-02-21 04:57:17 -08004744 &pfx_1_1_1_1_s_32,
4745 FIB_SOURCE_API,
4746 FIB_ENTRY_FLAG_NONE,
4747 DPO_PROTO_IP6,
4748 &nh_2001_2,
4749 tm->hw[0]->sw_if_index,
4750 ~0,
4751 1,
4752 NULL,
4753 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004754 FIB_TEST(fei == fib_table_lookup_exact_match(0, &pfx_1_1_1_1_s_32),
Neale Ranns2303cb12018-02-21 04:57:17 -08004755 "1.1.1.1/32 o v6 route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004756 ai = fib_entry_get_adj(fei);
4757 adj = adj_get(ai);
4758 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_ARP),
Neale Ranns2303cb12018-02-21 04:57:17 -08004759 "1.1.1.1/32 via ARP-adj");
Neale Ranns924d03a2016-10-19 08:25:46 +01004760 FIB_TEST((adj->ia_link == VNET_LINK_IP4),
Neale Ranns2303cb12018-02-21 04:57:17 -08004761 "1.1.1.1/32 ADJ-adj is link type v4");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004762 FIB_TEST((adj->ia_nh_proto == FIB_PROTOCOL_IP6),
Neale Ranns2303cb12018-02-21 04:57:17 -08004763 "1.1.1.1/32 ADJ-adj is NH proto v6");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004764 fib_table_entry_delete(0, &pfx_1_1_1_1_s_32, FIB_SOURCE_API);
4765
4766 /*
4767 * An attached route
4768 */
4769 fib_prefix_t pfx_2001_c_s_64 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004770 .fp_len = 64,
4771 .fp_proto = FIB_PROTOCOL_IP6,
4772 .fp_addr = {
4773 .ip6 = {
4774 .as_u64 = {
4775 [0] = clib_host_to_net_u64(0x200100000000000c),
4776 [1] = clib_host_to_net_u64(0x0000000000000000),
4777 },
4778 },
4779 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004780 };
4781 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004782 &pfx_2001_c_s_64,
4783 FIB_SOURCE_CLI,
4784 FIB_ENTRY_FLAG_ATTACHED,
4785 DPO_PROTO_IP6,
4786 NULL,
4787 tm->hw[0]->sw_if_index,
4788 ~0,
4789 1,
4790 NULL,
4791 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004792 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4793 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached route present");
4794 ai = fib_entry_get_adj(fei);
4795 adj = adj_get(ai);
4796 FIB_TEST((adj->lookup_next_index == IP_LOOKUP_NEXT_GLEAN),
Neale Ranns2303cb12018-02-21 04:57:17 -08004797 "2001:0:0:c/64 attached resolves via glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004798
4799 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08004800 &pfx_2001_c_s_64,
4801 FIB_SOURCE_CLI,
4802 DPO_PROTO_IP6,
4803 NULL,
4804 tm->hw[0]->sw_if_index,
4805 ~0,
4806 1,
4807 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004808 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_c_s_64);
4809 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached route removed");
4810
4811 /*
4812 * Shutdown the interface on which we have a connected and through
4813 * which the routes are reachable.
4814 * This will result in the connected, adj-fibs, and routes linking to drop
4815 * The local/for-us prefix continues to receive.
4816 */
4817 clib_error_t * error;
4818
4819 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004820 tm->hw[0]->sw_if_index,
4821 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004822 FIB_TEST((NULL == error), "Interface shutdown OK");
4823
4824 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4825 dpo = fib_entry_contribute_ip_forwarding(fei);
4826 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004827 "2001::b/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004828
4829 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4830 dpo = fib_entry_contribute_ip_forwarding(fei);
4831 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004832 "2001::a/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004833 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4834 dpo = fib_entry_contribute_ip_forwarding(fei);
4835 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004836 "2001:0:0:1::3/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004837 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4838 dpo = fib_entry_contribute_ip_forwarding(fei);
4839 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004840 "2001:0:0:1::2/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004841 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4842 dpo = fib_entry_contribute_ip_forwarding(fei);
4843 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004844 "2001:0:0:1::1/128 not drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004845 local_pfx.fp_len = 64;
4846 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4847 dpo = fib_entry_contribute_ip_forwarding(fei);
4848 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004849 "2001:0:0:1/64 resolves via drop");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004850
4851 /*
4852 * no change
4853 */
4854 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004855 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004856 FIB_TEST((PNPS+5 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004857 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004858 FIB_TEST((ENPS+6 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004859 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004860
4861 /*
4862 * shutdown one of the other interfaces, then add a connected.
4863 * and swap one of the routes to it.
4864 */
4865 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004866 tm->hw[1]->sw_if_index,
4867 ~VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004868 FIB_TEST((NULL == error), "Interface 1 shutdown OK");
4869
4870 fib_prefix_t connected_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08004871 .fp_len = 64,
4872 .fp_proto = FIB_PROTOCOL_IP6,
4873 .fp_addr = {
4874 .ip6 = {
4875 /* 2001:0:0:2::1/64 */
4876 .as_u64 = {
4877 [0] = clib_host_to_net_u64(0x2001000000000002),
4878 [1] = clib_host_to_net_u64(0x0000000000000001),
4879 },
4880 },
4881 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004882 };
4883 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004884 FIB_SOURCE_INTERFACE,
4885 (FIB_ENTRY_FLAG_CONNECTED |
4886 FIB_ENTRY_FLAG_ATTACHED),
4887 DPO_PROTO_IP6,
4888 NULL,
4889 tm->hw[1]->sw_if_index,
4890 ~0,
4891 1,
4892 NULL,
4893 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004894 fei = fib_table_lookup_exact_match(fib_index, &connected_pfx);
4895 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached interface route present");
4896 dpo = fib_entry_contribute_ip_forwarding(fei);
4897 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4898 FIB_TEST(!dpo_cmp(dpo, dpo_drop),
4899 "2001:0:0:2/64 not resolves via drop");
4900
4901 connected_pfx.fp_len = 128;
4902 fib_table_entry_update_one_path(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08004903 FIB_SOURCE_INTERFACE,
4904 (FIB_ENTRY_FLAG_CONNECTED |
4905 FIB_ENTRY_FLAG_LOCAL),
4906 DPO_PROTO_IP6,
4907 NULL,
4908 tm->hw[0]->sw_if_index,
4909 ~0, // invalid fib index
4910 1,
4911 NULL,
4912 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004913 fei = fib_table_lookup(fib_index, &connected_pfx);
4914
4915 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local interface route present");
4916 dpo = fib_entry_contribute_ip_forwarding(fei);
4917 dpo = load_balance_get_bucket(dpo->dpoi_index, 0);
4918 FIB_TEST((DPO_RECEIVE == dpo->dpoi_type),
Neale Ranns2303cb12018-02-21 04:57:17 -08004919 "local interface adj is local");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004920 rd = receive_dpo_get(dpo->dpoi_index);
4921 FIB_TEST((0 == ip46_address_cmp(&connected_pfx.fp_addr,
Neale Ranns2303cb12018-02-21 04:57:17 -08004922 &rd->rd_addr)),
4923 "local interface adj is receive ok");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004924
4925 /*
4926 * +2 entries, +2 unshared path-lists
4927 */
4928 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004929 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004930 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004931 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00004932 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08004933 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004934
4935
4936 /*
4937 * bring the interface back up. we expected the routes to return
4938 * to normal forwarding.
4939 */
4940 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004941 tm->hw[0]->sw_if_index,
4942 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004943 FIB_TEST((NULL == error), "Interface bring-up OK");
4944 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4945 ai = fib_entry_get_adj(fei);
4946 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
4947 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4948 ai = fib_entry_get_adj(fei);
4949 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
4950 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4951 ai = fib_entry_get_adj(fei);
4952 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
4953 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4954 ai = fib_entry_get_adj(fei);
4955 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
4956 local_pfx.fp_len = 64;
4957 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4958 ai = fib_entry_get_adj(fei);
4959 adj = adj_get(ai);
4960 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08004961 "attached interface adj is glean");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01004962
4963 /*
Neale Ranns8b37b872016-11-21 12:25:22 +00004964 * Same test as above, but this time the HW interface goes down
4965 */
4966 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004967 tm->hw_if_indicies[0],
4968 ~VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00004969 FIB_TEST((NULL == error), "Interface shutdown OK");
4970
4971 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
4972 dpo = fib_entry_contribute_ip_forwarding(fei);
4973 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004974 "2001::b/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004975 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
4976 dpo = fib_entry_contribute_ip_forwarding(fei);
4977 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004978 "2001::a/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004979 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
4980 dpo = fib_entry_contribute_ip_forwarding(fei);
4981 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004982 "2001:0:0:1::3/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004983 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
4984 dpo = fib_entry_contribute_ip_forwarding(fei);
4985 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004986 "2001:0:0:1::2/128 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004987 local_pfx.fp_len = 128;
4988 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4989 dpo = fib_entry_contribute_ip_forwarding(fei);
4990 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004991 "2001:0:0:1::1/128 not drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004992 local_pfx.fp_len = 64;
4993 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
4994 dpo = fib_entry_contribute_ip_forwarding(fei);
4995 FIB_TEST(!dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08004996 "2001:0:0:1/64 resolves via drop");
Neale Ranns8b37b872016-11-21 12:25:22 +00004997
4998 error = vnet_hw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08004999 tm->hw_if_indicies[0],
5000 VNET_HW_INTERFACE_FLAG_LINK_UP);
Neale Ranns8b37b872016-11-21 12:25:22 +00005001 FIB_TEST((NULL == error), "Interface bring-up OK");
5002 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64);
5003 ai = fib_entry_get_adj(fei);
5004 FIB_TEST((ai_01 == ai), "2001::a/64 resolves via 2001:0:0:1::1");
5005 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5006 ai = fib_entry_get_adj(fei);
5007 FIB_TEST((ai_01 == ai), "2001::b/64 resolves via 2001:0:0:1::1");
5008 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_3_s_128);
5009 ai = fib_entry_get_adj(fei);
5010 FIB_TEST((ai_02 == ai), "ADJ-FIB resolves via adj");
5011 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5012 ai = fib_entry_get_adj(fei);
5013 FIB_TEST((ai_01 == ai), "ADJ-FIB resolves via adj");
5014 local_pfx.fp_len = 64;
5015 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5016 ai = fib_entry_get_adj(fei);
5017 adj = adj_get(ai);
5018 FIB_TEST((IP_LOOKUP_NEXT_GLEAN == adj->lookup_next_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08005019 "attached interface adj is glean");
Neale Ranns8b37b872016-11-21 12:25:22 +00005020
5021 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005022 * Delete the interface that the routes reolve through.
5023 * Again no routes are removed. They all point to drop.
5024 *
5025 * This is considered an error case. The control plane should
5026 * not remove interfaces through which routes resolve, but
5027 * such things can happen. ALL affected routes will drop.
5028 */
5029 vnet_delete_hw_interface(vnet_get_main(), tm->hw_if_indicies[0]);
5030
5031 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5032 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5033 "2001::b/64 resolves via drop");
5034 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_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_1_3_s_128);
5038 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5039 "2001:0:0:1::3/64 resolves via drop");
5040 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5041 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5042 "2001:0:0:1::2/64 resolves via drop");
5043 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5044 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5045 "2001:0:0:1::1/128 is drop");
5046 local_pfx.fp_len = 64;
5047 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5048 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5049 "2001:0:0:1/64 resolves via drop");
5050
5051 /*
5052 * no change
5053 */
5054 FIB_TEST((1 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005055 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005056 FIB_TEST((PNPS+7 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005057 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005058 FIB_TEST((ENPS+8 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005059 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005060
5061 /*
5062 * Add the interface back. routes stay unresolved.
5063 */
5064 error = ethernet_register_interface(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005065 test_interface_device_class.index,
5066 0 /* instance */,
5067 hw_address,
5068 &tm->hw_if_indicies[0],
5069 /* flag change */ 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005070
5071 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64);
5072 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5073 "2001::b/64 resolves via drop");
5074 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_a_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_1_3_s_128);
5078 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5079 "2001:0:0:1::3/64 resolves via drop");
5080 fei = fib_table_lookup_exact_match(fib_index, &pfx_2001_1_2_s_128);
5081 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5082 "2001:0:0:1::2/64 resolves via drop");
5083 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5084 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5085 "2001:0:0:1::1/128 is drop");
5086 local_pfx.fp_len = 64;
5087 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5088 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
5089 "2001:0:0:1/64 resolves via drop");
5090
5091 /*
5092 * CLEANUP ALL the routes
5093 */
5094 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005095 &pfx_2001_c_s_64,
5096 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005097 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005098 &pfx_2001_a_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_b_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_1_3_s_128,
5105 FIB_SOURCE_ADJ);
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_2_s_128,
5108 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005109 local_pfx.fp_len = 64;
5110 fib_table_entry_delete(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005111 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005112 local_pfx.fp_len = 128;
5113 fib_table_entry_special_remove(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005114 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005115 connected_pfx.fp_len = 64;
5116 fib_table_entry_delete(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005117 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005118 connected_pfx.fp_len = 128;
5119 fib_table_entry_special_remove(fib_index, &connected_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005120 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005121
5122 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005123 fib_table_lookup_exact_match(fib_index, &pfx_2001_a_s_64)),
5124 "2001::a/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005125 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005126 fib_table_lookup_exact_match(fib_index, &pfx_2001_b_s_64)),
5127 "2001::b/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_1_3_s_128)),
5130 "2001:0:0:1::3/128 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_2_s_128)),
5133 "2001:0:0:1::3/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005134 local_pfx.fp_len = 64;
5135 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005136 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5137 "2001:0:0:1/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005138 local_pfx.fp_len = 128;
5139 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005140 fib_table_lookup_exact_match(fib_index, &local_pfx)),
5141 "2001:0:0:1::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005142 connected_pfx.fp_len = 64;
5143 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005144 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5145 "2001:0:0:2/64 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005146 connected_pfx.fp_len = 128;
5147 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08005148 fib_table_lookup_exact_match(fib_index, &connected_pfx)),
5149 "2001:0:0:2::1/128 removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005150
5151 /*
5152 * -8 entries. -7 path-lists (1 was shared).
5153 */
5154 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005155 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005156 FIB_TEST((PNPS == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005157 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005158 FIB_TEST((ENPS == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005159 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005160
5161 /*
5162 * now remove the VRF
5163 */
Neale Ranns15002542017-09-10 04:39:11 -07005164 fib_table_unlock(fib_index, FIB_PROTOCOL_IP6, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005165
5166 FIB_TEST((0 == fib_path_list_db_size()), "path list DB population:%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005167 fib_path_list_db_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005168 FIB_TEST((PNPS-2 == fib_path_list_pool_size()), "path list pool size is%d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005169 fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00005170 FIB_TEST((ENPS-2 == fib_entry_pool_size()), "entry pool size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005171 fib_entry_pool_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005172
5173 adj_unlock(ai_02);
5174 adj_unlock(ai_01);
5175
5176 /*
5177 * return the interfaces to up state
5178 */
5179 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005180 tm->hw[0]->sw_if_index,
5181 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005182 error = vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08005183 tm->hw[1]->sw_if_index,
5184 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005185
5186 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005187 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005188
Neale Ranns2303cb12018-02-21 04:57:17 -08005189 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005190}
5191
5192/*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005193 * Test Attached Exports
5194 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005195static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005196fib_test_ae (void)
5197{
5198 const dpo_id_t *dpo, *dpo_drop;
5199 const u32 fib_index = 0;
5200 fib_node_index_t fei;
5201 test_main_t *tm;
5202 ip4_main_t *im;
Neale Ranns2303cb12018-02-21 04:57:17 -08005203 int res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005204
Neale Ranns2303cb12018-02-21 04:57:17 -08005205 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005206 tm = &test_main;
5207 im = &ip4_main;
5208
5209 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005210 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005211
5212 /*
5213 * add interface routes. We'll assume this works. It's more rigorously
5214 * tested elsewhere.
5215 */
5216 fib_prefix_t local_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005217 .fp_len = 24,
5218 .fp_proto = FIB_PROTOCOL_IP4,
5219 .fp_addr = {
5220 .ip4 = {
5221 /* 10.10.10.10 */
5222 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
5223 },
5224 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005225 };
5226
5227 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
5228 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
5229
5230 dpo_drop = drop_dpo_get(DPO_PROTO_IP4);
5231
5232 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005233 FIB_SOURCE_INTERFACE,
5234 (FIB_ENTRY_FLAG_CONNECTED |
5235 FIB_ENTRY_FLAG_ATTACHED),
5236 DPO_PROTO_IP4,
5237 NULL,
5238 tm->hw[0]->sw_if_index,
5239 ~0,
5240 1,
5241 NULL,
5242 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005243 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5244 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005245 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005246
5247 local_pfx.fp_len = 32;
5248 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005249 FIB_SOURCE_INTERFACE,
5250 (FIB_ENTRY_FLAG_CONNECTED |
5251 FIB_ENTRY_FLAG_LOCAL),
5252 DPO_PROTO_IP4,
5253 NULL,
5254 tm->hw[0]->sw_if_index,
5255 ~0, // invalid fib index
5256 1,
5257 NULL,
5258 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005259 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5260
5261 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08005262 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005263
5264 /*
5265 * Add an 2 ARP entry => a complete ADJ plus adj-fib.
5266 */
5267 fib_prefix_t pfx_10_10_10_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005268 .fp_len = 32,
5269 .fp_proto = FIB_PROTOCOL_IP4,
5270 .fp_addr = {
5271 /* 10.10.10.1 */
5272 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5273 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005274 };
5275 fib_node_index_t ai;
5276
Neale Ranns81424992017-05-18 03:03:22 -07005277 fib_table_entry_path_add(fib_index,
5278 &pfx_10_10_10_1_s_32,
5279 FIB_SOURCE_ADJ,
5280 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005281 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005282 &pfx_10_10_10_1_s_32.fp_addr,
5283 tm->hw[0]->sw_if_index,
5284 ~0, // invalid fib index
5285 1,
5286 NULL,
5287 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005288
5289 fei = fib_table_lookup(fib_index, &pfx_10_10_10_1_s_32);
5290 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 created");
5291 ai = fib_entry_get_adj(fei);
5292
5293 /*
5294 * create another FIB table into which routes will be imported
5295 */
5296 u32 import_fib_index1;
5297
Neale Ranns15002542017-09-10 04:39:11 -07005298 import_fib_index1 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4,
5299 11,
5300 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005301
5302 /*
5303 * Add an attached route in the import FIB
5304 */
5305 local_pfx.fp_len = 24;
5306 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005307 &local_pfx,
5308 FIB_SOURCE_API,
5309 FIB_ENTRY_FLAG_NONE,
5310 DPO_PROTO_IP4,
5311 NULL,
5312 tm->hw[0]->sw_if_index,
5313 ~0, // invalid fib index
5314 1,
5315 NULL,
5316 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005317 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5318 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5319
5320 /*
5321 * check for the presence of the adj-fibs in the import table
5322 */
5323 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5324 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5325 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005326 "adj-fib1 Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005327
5328 /*
5329 * check for the presence of the local in the import table
5330 */
5331 local_pfx.fp_len = 32;
5332 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5333 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5334
5335 /*
5336 * Add another adj-fin in the export table. Expect this
5337 * to get magically exported;
5338 */
5339 fib_prefix_t pfx_10_10_10_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005340 .fp_len = 32,
5341 .fp_proto = FIB_PROTOCOL_IP4,
5342 .fp_addr = {
5343 /* 10.10.10.2 */
5344 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5345 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005346 };
5347
Neale Ranns81424992017-05-18 03:03:22 -07005348 fib_table_entry_path_add(fib_index,
5349 &pfx_10_10_10_2_s_32,
5350 FIB_SOURCE_ADJ,
5351 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005352 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005353 &pfx_10_10_10_2_s_32.fp_addr,
5354 tm->hw[0]->sw_if_index,
5355 ~0, // invalid fib index
5356 1,
5357 NULL,
5358 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005359 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5360 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 present");
5361 ai = fib_entry_get_adj(fei);
5362
5363 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5364 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5365 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005366 "Import uses same adj as export");
Neale Rannsfa0fb582016-12-10 21:59:14 +00005367 FIB_TEST((FIB_ENTRY_FLAG_ATTACHED & fib_entry_get_flags(fei)),
5368 "ADJ-fib2 imported flags %d",
5369 fib_entry_get_flags(fei));
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005370
5371 /*
5372 * create a 2nd FIB table into which routes will be imported
5373 */
5374 u32 import_fib_index2;
5375
Neale Ranns15002542017-09-10 04:39:11 -07005376 import_fib_index2 = fib_table_find_or_create_and_lock(FIB_PROTOCOL_IP4, 12,
5377 FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005378
5379 /*
5380 * Add an attached route in the import FIB
5381 */
5382 local_pfx.fp_len = 24;
5383 fib_table_entry_update_one_path(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005384 &local_pfx,
5385 FIB_SOURCE_API,
5386 FIB_ENTRY_FLAG_NONE,
5387 DPO_PROTO_IP4,
5388 NULL,
5389 tm->hw[0]->sw_if_index,
5390 ~0, // invalid fib index
5391 1,
5392 NULL,
5393 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005394 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5395 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached export created");
5396
5397 /*
5398 * check for the presence of all the adj-fibs and local in the import table
5399 */
5400 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5401 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5402 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5403 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5404 local_pfx.fp_len = 32;
5405 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5406 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5407
5408 /*
5409 * add a 3rd adj-fib. expect it to be exported to both tables.
5410 */
5411 fib_prefix_t pfx_10_10_10_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005412 .fp_len = 32,
5413 .fp_proto = FIB_PROTOCOL_IP4,
5414 .fp_addr = {
5415 /* 10.10.10.3 */
5416 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
5417 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005418 };
5419
Neale Ranns81424992017-05-18 03:03:22 -07005420 fib_table_entry_path_add(fib_index,
5421 &pfx_10_10_10_3_s_32,
5422 FIB_SOURCE_ADJ,
5423 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07005424 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07005425 &pfx_10_10_10_3_s_32.fp_addr,
5426 tm->hw[0]->sw_if_index,
5427 ~0, // invalid fib index
5428 1,
5429 NULL,
5430 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005431 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5432 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 present");
5433 ai = fib_entry_get_adj(fei);
5434
5435 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5436 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB1");
5437 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005438 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005439 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5440 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib3 imported to FIB2");
5441 FIB_TEST((ai == fib_entry_get_adj(fei)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005442 "Import uses same adj as export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005443
5444 /*
5445 * remove the 3rd adj fib. we expect it to be removed from both FIBs
5446 */
5447 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005448 &pfx_10_10_10_3_s_32,
5449 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005450
5451 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_3_s_32);
5452 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 remved");
5453
5454 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_3_s_32);
5455 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB1");
5456
5457 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_3_s_32);
5458 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib3 removed from FIB2");
5459
5460 /*
5461 * remove the attached route from the 2nd FIB. expect the imported
5462 * entires to be removed
5463 */
5464 local_pfx.fp_len = 24;
5465 fib_table_entry_delete(import_fib_index2,
Neale Ranns2303cb12018-02-21 04:57:17 -08005466 &local_pfx,
5467 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005468 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5469 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "attached export removed");
5470
5471 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_1_s_32);
5472 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB2");
5473 fei = fib_table_lookup_exact_match(import_fib_index2, &pfx_10_10_10_2_s_32);
5474 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB2");
5475 local_pfx.fp_len = 32;
5476 fei = fib_table_lookup_exact_match(import_fib_index2, &local_pfx);
5477 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB2");
5478
5479 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5480 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 still in FIB1");
5481 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5482 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 still in FIB1");
5483 local_pfx.fp_len = 32;
5484 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5485 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local still in FIB1");
5486
5487 /*
5488 * modify the route in FIB1 so it is no longer attached. expect the imported
5489 * entires to be removed
5490 */
5491 local_pfx.fp_len = 24;
5492 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005493 &local_pfx,
5494 FIB_SOURCE_API,
5495 FIB_ENTRY_FLAG_NONE,
5496 DPO_PROTO_IP4,
5497 &pfx_10_10_10_2_s_32.fp_addr,
5498 tm->hw[0]->sw_if_index,
5499 ~0, // invalid fib index
5500 1,
5501 NULL,
5502 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005503 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5504 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5505 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5506 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5507 local_pfx.fp_len = 32;
5508 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5509 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5510
5511 /*
5512 * modify it back to attached. expect the adj-fibs back
5513 */
5514 local_pfx.fp_len = 24;
5515 fib_table_entry_update_one_path(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005516 &local_pfx,
5517 FIB_SOURCE_API,
5518 FIB_ENTRY_FLAG_NONE,
5519 DPO_PROTO_IP4,
5520 NULL,
5521 tm->hw[0]->sw_if_index,
5522 ~0, // invalid fib index
5523 1,
5524 NULL,
5525 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005526 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5527 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported in FIB1");
5528 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5529 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported in FIB1");
5530 local_pfx.fp_len = 32;
5531 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5532 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported in FIB1");
5533
5534 /*
5535 * add a covering attached next-hop for the interface address, so we have
5536 * a valid adj to find when we check the forwarding tables
5537 */
5538 fib_prefix_t pfx_10_0_0_0_s_8 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08005539 .fp_len = 8,
5540 .fp_proto = FIB_PROTOCOL_IP4,
5541 .fp_addr = {
5542 /* 10.0.0.0 */
5543 .ip4.as_u32 = clib_host_to_net_u32(0x0a000000),
5544 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005545 };
5546
5547 fei = fib_table_entry_update_one_path(fib_index,
5548 &pfx_10_0_0_0_s_8,
5549 FIB_SOURCE_API,
5550 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005551 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005552 &pfx_10_10_10_3_s_32.fp_addr,
5553 tm->hw[0]->sw_if_index,
5554 ~0, // invalid fib index
5555 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005556 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005557 FIB_ROUTE_PATH_FLAG_NONE);
5558 dpo = fib_entry_contribute_ip_forwarding(fei);
5559
5560 /*
5561 * remove the route in the export fib. expect the adj-fibs to be removed
5562 */
5563 local_pfx.fp_len = 24;
5564 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005565 &local_pfx,
5566 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005567
5568 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5569 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "Delete export: ADJ-fib1 removed from FIB1");
5570 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5571 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5572 local_pfx.fp_len = 32;
5573 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5574 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5575
5576 /*
5577 * the adj-fibs in the export VRF are present in the FIB table,
5578 * but not installed in forwarding, since they have no attached cover.
5579 * Consequently a lookup in the MTRIE gives the adj for the covering
5580 * route 10.0.0.0/8.
5581 */
5582 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5583 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5584
5585 index_t lbi;
5586 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5587 FIB_TEST(lbi == dpo->dpoi_index,
5588 "10.10.10.1 forwards on \n%U not \n%U",
5589 format_load_balance, lbi, 0,
5590 format_dpo_id, dpo, 0);
5591 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5592 FIB_TEST(lbi == dpo->dpoi_index,
5593 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5594 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_3_s_32.fp_addr.ip4);
5595 FIB_TEST(lbi == dpo->dpoi_index,
5596 "10.10.10.3 forwards on %U", format_dpo_id, dpo, 0);
5597
5598 /*
5599 * add the export prefix back, but not as attached.
5600 * No adj-fibs in export nor import tables
5601 */
5602 local_pfx.fp_len = 24;
5603 fei = fib_table_entry_update_one_path(fib_index,
5604 &local_pfx,
5605 FIB_SOURCE_API,
5606 FIB_ENTRY_FLAG_NONE,
Neale Ranns2303cb12018-02-21 04:57:17 -08005607 DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005608 &pfx_10_10_10_1_s_32.fp_addr,
5609 tm->hw[0]->sw_if_index,
5610 ~0, // invalid fib index
5611 1,
Neale Rannsad422ed2016-11-02 14:20:04 +00005612 NULL,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005613 FIB_ROUTE_PATH_FLAG_NONE);
5614 dpo = fib_entry_contribute_ip_forwarding(fei);
5615
5616 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5617 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "non-attached in export: ADJ-fib1 in export");
5618 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_1_s_32.fp_addr.ip4);
5619 FIB_TEST(lbi == dpo->dpoi_index,
5620 "10.10.10.1 forwards on %U", format_dpo_id, dpo, 0);
5621 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5622 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 in export");
5623 lbi = ip4_fib_forwarding_lookup(fib_index, &pfx_10_10_10_2_s_32.fp_addr.ip4);
5624 FIB_TEST(lbi == dpo->dpoi_index,
5625 "10.10.10.2 forwards on %U", format_dpo_id, dpo, 0);
5626
5627 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5628 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib1 removed from FIB1");
5629 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5630 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "ADJ-fib2 removed from FIB1");
5631 local_pfx.fp_len = 32;
5632 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5633 FIB_TEST((FIB_NODE_INDEX_INVALID == fei), "local removed from FIB1");
5634
5635 /*
5636 * modify the export prefix so it is attached. expect all covereds to return
5637 */
5638 local_pfx.fp_len = 24;
5639 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005640 &local_pfx,
5641 FIB_SOURCE_API,
5642 FIB_ENTRY_FLAG_NONE,
5643 DPO_PROTO_IP4,
5644 NULL,
5645 tm->hw[0]->sw_if_index,
5646 ~0, // invalid fib index
5647 1,
5648 NULL,
5649 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005650
5651 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5652 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5653 dpo = fib_entry_contribute_ip_forwarding(fei);
5654 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005655 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005656 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5657 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5658 local_pfx.fp_len = 32;
5659 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5660 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5661 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5662 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5663 dpo = fib_entry_contribute_ip_forwarding(fei);
5664 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005665 "Adj-fib1 is not drop in export: %U %U",
5666 format_dpo_id, dpo, 0,
5667 format_dpo_id, load_balance_get_bucket(dpo->dpoi_index, 0), 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005668 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5669 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 imported");
5670 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5671 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5672 local_pfx.fp_len = 32;
5673 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5674 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5675
5676 /*
5677 * modify the export prefix so connected. no change.
5678 */
5679 local_pfx.fp_len = 24;
5680 fib_table_entry_update_one_path(fib_index, &local_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08005681 FIB_SOURCE_INTERFACE,
5682 (FIB_ENTRY_FLAG_CONNECTED |
5683 FIB_ENTRY_FLAG_ATTACHED),
5684 DPO_PROTO_IP4,
5685 NULL,
5686 tm->hw[0]->sw_if_index,
5687 ~0,
5688 1,
5689 NULL,
5690 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005691
5692 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_1_s_32);
5693 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib1 reinstalled in export");
5694 dpo = fib_entry_contribute_ip_forwarding(fei);
5695 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005696 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005697 fei = fib_table_lookup_exact_match(fib_index, &pfx_10_10_10_2_s_32);
5698 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 reinstalled in export");
5699 local_pfx.fp_len = 32;
5700 fei = fib_table_lookup_exact_match(fib_index, &local_pfx);
5701 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local reinstalled in export");
5702 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_1_s_32);
5703 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "attached in export: ADJ-fib1 imported");
5704 dpo = fib_entry_contribute_ip_forwarding(fei);
5705 FIB_TEST(dpo_cmp(dpo_drop, load_balance_get_bucket(dpo->dpoi_index, 0)),
Neale Ranns2303cb12018-02-21 04:57:17 -08005706 "Adj-fib1 is not drop in export");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005707 fei = fib_table_lookup_exact_match(import_fib_index1, &pfx_10_10_10_2_s_32);
5708 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "ADJ-fib2 imported");
5709 local_pfx.fp_len = 32;
5710 fei = fib_table_lookup_exact_match(import_fib_index1, &local_pfx);
5711 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "local imported");
5712
5713 /*
5714 * CLEANUP
5715 */
5716 fib_table_entry_delete(fib_index,
5717 &pfx_10_0_0_0_s_8,
5718 FIB_SOURCE_API);
5719 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005720 &pfx_10_10_10_1_s_32,
5721 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005722 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005723 &pfx_10_10_10_2_s_32,
5724 FIB_SOURCE_ADJ);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005725 local_pfx.fp_len = 32;
5726 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005727 &local_pfx,
5728 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005729 local_pfx.fp_len = 24;
5730 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005731 &local_pfx,
5732 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005733 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08005734 &local_pfx,
5735 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005736 local_pfx.fp_len = 24;
5737 fib_table_entry_delete(import_fib_index1,
Neale Ranns2303cb12018-02-21 04:57:17 -08005738 &local_pfx,
5739 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005740
Neale Ranns15002542017-09-10 04:39:11 -07005741 fib_table_unlock(import_fib_index1, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
5742 fib_table_unlock(import_fib_index2, FIB_PROTOCOL_IP4, FIB_SOURCE_CLI);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005743
5744 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08005745 adj_nbr_db_size());
Neale Ranns0ebe8d72016-12-08 19:48:11 +00005746
Neale Ranns2303cb12018-02-21 04:57:17 -08005747 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01005748}
5749
Neale Ranns57b58602017-07-15 07:37:25 -07005750/*
5751 * Test Path Preference
5752 */
5753static int
5754fib_test_pref (void)
5755{
5756 test_main_t *tm = &test_main;
Neale Ranns2303cb12018-02-21 04:57:17 -08005757 int res;
Neale Ranns57b58602017-07-15 07:37:25 -07005758
Neale Ranns2303cb12018-02-21 04:57:17 -08005759 res = 0;
Neale Ranns57b58602017-07-15 07:37:25 -07005760 const fib_prefix_t pfx_1_1_1_1_s_32 = {
5761 .fp_len = 32,
5762 .fp_proto = FIB_PROTOCOL_IP4,
5763 .fp_addr = {
5764 .ip4 = {
5765 .as_u32 = clib_host_to_net_u32(0x01010101),
5766 },
5767 },
5768 };
5769
5770 /*
5771 * 2 high, 2 medium and 2 low preference non-recursive paths
5772 */
5773 fib_route_path_t nr_path_hi_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005774 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005775 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5776 .frp_fib_index = ~0,
5777 .frp_weight = 1,
5778 .frp_preference = 0,
5779 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5780 .frp_addr = {
5781 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
5782 },
5783 };
5784 fib_route_path_t nr_path_hi_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005785 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005786 .frp_sw_if_index = tm->hw[0]->sw_if_index,
5787 .frp_fib_index = ~0,
5788 .frp_weight = 1,
5789 .frp_preference = 0,
5790 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5791 .frp_addr = {
5792 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
5793 },
5794 };
5795 fib_route_path_t nr_path_med_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005796 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005797 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5798 .frp_fib_index = ~0,
5799 .frp_weight = 1,
5800 .frp_preference = 1,
5801 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5802 .frp_addr = {
5803 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5804 },
5805 };
5806 fib_route_path_t nr_path_med_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005807 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005808 .frp_sw_if_index = tm->hw[1]->sw_if_index,
5809 .frp_fib_index = ~0,
5810 .frp_weight = 1,
5811 .frp_preference = 1,
5812 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5813 .frp_addr = {
5814 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0c01),
5815 },
5816 };
5817 fib_route_path_t nr_path_low_1 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005818 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005819 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5820 .frp_fib_index = ~0,
5821 .frp_weight = 1,
5822 .frp_preference = 2,
5823 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5824 .frp_addr = {
5825 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b01),
5826 },
5827 };
5828 fib_route_path_t nr_path_low_2 = {
Neale Rannsda78f952017-05-24 09:15:43 -07005829 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07005830 .frp_sw_if_index = tm->hw[2]->sw_if_index,
5831 .frp_fib_index = ~0,
5832 .frp_weight = 1,
5833 .frp_preference = 2,
5834 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
5835 .frp_addr = {
5836 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0b02),
5837 },
5838 };
5839 fib_route_path_t *nr_paths = NULL;
5840
5841 vec_add1(nr_paths, nr_path_hi_1);
5842 vec_add1(nr_paths, nr_path_hi_2);
5843 vec_add1(nr_paths, nr_path_med_1);
5844 vec_add1(nr_paths, nr_path_med_2);
5845 vec_add1(nr_paths, nr_path_low_1);
5846 vec_add1(nr_paths, nr_path_low_2);
5847
5848 adj_index_t ai_hi_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5849 VNET_LINK_IP4,
5850 &nr_path_hi_1.frp_addr,
5851 nr_path_hi_1.frp_sw_if_index);
5852 adj_index_t ai_hi_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5853 VNET_LINK_IP4,
5854 &nr_path_hi_2.frp_addr,
5855 nr_path_hi_2.frp_sw_if_index);
5856 adj_index_t ai_med_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5857 VNET_LINK_IP4,
5858 &nr_path_med_1.frp_addr,
5859 nr_path_med_1.frp_sw_if_index);
5860 adj_index_t ai_med_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5861 VNET_LINK_IP4,
5862 &nr_path_med_2.frp_addr,
5863 nr_path_med_2.frp_sw_if_index);
5864 adj_index_t ai_low_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5865 VNET_LINK_IP4,
5866 &nr_path_low_1.frp_addr,
5867 nr_path_low_1.frp_sw_if_index);
5868 adj_index_t ai_low_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
5869 VNET_LINK_IP4,
5870 &nr_path_low_2.frp_addr,
5871 nr_path_low_2.frp_sw_if_index);
5872
5873 fib_test_lb_bucket_t ip_hi_1 = {
5874 .type = FT_LB_ADJ,
5875 .adj = {
5876 .adj = ai_hi_1,
5877 },
5878 };
5879 fib_test_lb_bucket_t ip_hi_2 = {
5880 .type = FT_LB_ADJ,
5881 .adj = {
5882 .adj = ai_hi_2,
5883 },
5884 };
5885 fib_test_lb_bucket_t ip_med_1 = {
5886 .type = FT_LB_ADJ,
5887 .adj = {
5888 .adj = ai_med_1,
5889 },
5890 };
5891 fib_test_lb_bucket_t ip_med_2 = {
5892 .type = FT_LB_ADJ,
5893 .adj = {
5894 .adj = ai_med_2,
5895 },
5896 };
5897 fib_test_lb_bucket_t ip_low_1 = {
5898 .type = FT_LB_ADJ,
5899 .adj = {
5900 .adj = ai_low_1,
5901 },
5902 };
5903 fib_test_lb_bucket_t ip_low_2 = {
5904 .type = FT_LB_ADJ,
5905 .adj = {
5906 .adj = ai_low_2,
5907 },
5908 };
5909
5910 fib_node_index_t fei;
5911
5912 fei = fib_table_entry_path_add2(0,
5913 &pfx_1_1_1_1_s_32,
5914 FIB_SOURCE_API,
5915 FIB_ENTRY_FLAG_NONE,
5916 nr_paths);
5917
Neale Ranns2303cb12018-02-21 04:57:17 -08005918 FIB_TEST(!fib_test_validate_entry(fei,
5919 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5920 2,
5921 &ip_hi_1,
5922 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005923 "1.1.1.1/32 via high preference paths");
5924
5925 /*
5926 * bring down the interface on which the high preference path lie
5927 */
5928 vnet_sw_interface_set_flags(vnet_get_main(),
5929 tm->hw[0]->sw_if_index,
5930 0);
5931
Neale Ranns2303cb12018-02-21 04:57:17 -08005932 FIB_TEST(!fib_test_validate_entry(fei,
5933 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5934 2,
5935 &ip_med_1,
5936 &ip_med_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005937 "1.1.1.1/32 via medium preference paths");
5938
5939 /*
5940 * bring down the interface on which the medium preference path lie
5941 */
5942 vnet_sw_interface_set_flags(vnet_get_main(),
5943 tm->hw[1]->sw_if_index,
5944 0);
5945
Neale Ranns2303cb12018-02-21 04:57:17 -08005946 FIB_TEST(!fib_test_validate_entry(fei,
5947 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5948 2,
5949 &ip_low_1,
5950 &ip_low_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005951 "1.1.1.1/32 via low preference paths");
5952
5953 /*
5954 * bring up the interface on which the high preference path lie
5955 */
5956 vnet_sw_interface_set_flags(vnet_get_main(),
5957 tm->hw[0]->sw_if_index,
5958 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5959
Neale Ranns2303cb12018-02-21 04:57:17 -08005960 FIB_TEST(!fib_test_validate_entry(fei,
5961 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5962 2,
5963 &ip_hi_1,
5964 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005965 "1.1.1.1/32 via high preference paths");
5966
5967 /*
5968 * bring up the interface on which the medium preference path lie
5969 */
5970 vnet_sw_interface_set_flags(vnet_get_main(),
5971 tm->hw[1]->sw_if_index,
5972 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
5973
Neale Ranns2303cb12018-02-21 04:57:17 -08005974 FIB_TEST(!fib_test_validate_entry(fei,
5975 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5976 2,
5977 &ip_hi_1,
5978 &ip_hi_2),
Neale Ranns57b58602017-07-15 07:37:25 -07005979 "1.1.1.1/32 via high preference paths");
5980
5981 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
5982 fib_entry_contribute_forwarding(fei,
5983 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
5984 &ip_1_1_1_1);
5985
5986 /*
5987 * 3 recursive paths of different preference
5988 */
5989 const fib_prefix_t pfx_1_1_1_2_s_32 = {
5990 .fp_len = 32,
5991 .fp_proto = FIB_PROTOCOL_IP4,
5992 .fp_addr = {
5993 .ip4 = {
5994 .as_u32 = clib_host_to_net_u32(0x01010102),
5995 },
5996 },
5997 };
5998 const fib_prefix_t pfx_1_1_1_3_s_32 = {
5999 .fp_len = 32,
6000 .fp_proto = FIB_PROTOCOL_IP4,
6001 .fp_addr = {
6002 .ip4 = {
6003 .as_u32 = clib_host_to_net_u32(0x01010103),
6004 },
6005 },
6006 };
6007 fei = fib_table_entry_path_add2(0,
6008 &pfx_1_1_1_2_s_32,
6009 FIB_SOURCE_API,
6010 FIB_ENTRY_FLAG_NONE,
6011 nr_paths);
6012 dpo_id_t ip_1_1_1_2 = DPO_INVALID;
6013 fib_entry_contribute_forwarding(fei,
6014 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6015 &ip_1_1_1_2);
6016 fei = fib_table_entry_path_add2(0,
6017 &pfx_1_1_1_3_s_32,
6018 FIB_SOURCE_API,
6019 FIB_ENTRY_FLAG_NONE,
6020 nr_paths);
6021 dpo_id_t ip_1_1_1_3 = DPO_INVALID;
6022 fib_entry_contribute_forwarding(fei,
6023 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6024 &ip_1_1_1_3);
6025
6026 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
6027 .type = FT_LB_O_LB,
6028 .lb = {
6029 .lb = ip_1_1_1_1.dpoi_index,
6030 },
6031 };
6032 fib_test_lb_bucket_t ip_o_1_1_1_2 = {
6033 .type = FT_LB_O_LB,
6034 .lb = {
6035 .lb = ip_1_1_1_2.dpoi_index,
6036 },
6037 };
6038 fib_test_lb_bucket_t ip_o_1_1_1_3 = {
6039 .type = FT_LB_O_LB,
6040 .lb = {
6041 .lb = ip_1_1_1_3.dpoi_index,
6042 },
6043 };
6044 fib_route_path_t r_path_hi = {
Neale Rannsda78f952017-05-24 09:15:43 -07006045 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006046 .frp_sw_if_index = ~0,
6047 .frp_fib_index = 0,
6048 .frp_weight = 1,
6049 .frp_preference = 0,
6050 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6051 .frp_addr = pfx_1_1_1_1_s_32.fp_addr,
6052 };
6053 fib_route_path_t r_path_med = {
Neale Rannsda78f952017-05-24 09:15:43 -07006054 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006055 .frp_sw_if_index = ~0,
6056 .frp_fib_index = 0,
6057 .frp_weight = 1,
6058 .frp_preference = 10,
6059 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
6060 .frp_addr = pfx_1_1_1_2_s_32.fp_addr,
6061 };
6062 fib_route_path_t r_path_low = {
Neale Rannsda78f952017-05-24 09:15:43 -07006063 .frp_proto = DPO_PROTO_IP4,
Neale Ranns57b58602017-07-15 07:37:25 -07006064 .frp_sw_if_index = ~0,
6065 .frp_fib_index = 0,
6066 .frp_weight = 1,
Neale Rannsa0a908f2017-08-01 11:40:03 -07006067 .frp_preference = 255,
Neale Ranns57b58602017-07-15 07:37:25 -07006068 .frp_flags = FIB_ROUTE_PATH_RESOLVE_VIA_HOST,
6069 .frp_addr = pfx_1_1_1_3_s_32.fp_addr,
6070 };
6071 fib_route_path_t *r_paths = NULL;
6072
6073 vec_add1(r_paths, r_path_hi);
6074 vec_add1(r_paths, r_path_low);
6075 vec_add1(r_paths, r_path_med);
6076
6077 /*
6078 * add many recursive so we get the LB MAp created
6079 */
Neale Ranns2303cb12018-02-21 04:57:17 -08006080#define N_PFXS 64
Neale Ranns57b58602017-07-15 07:37:25 -07006081 fib_prefix_t pfx_r[N_PFXS];
Marek Gradzkiaf095512017-08-15 07:38:26 +02006082 unsigned int n_pfxs;
Neale Ranns57b58602017-07-15 07:37:25 -07006083 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6084 {
6085 pfx_r[n_pfxs].fp_len = 32;
6086 pfx_r[n_pfxs].fp_proto = FIB_PROTOCOL_IP4;
6087 pfx_r[n_pfxs].fp_addr.ip4.as_u32 =
6088 clib_host_to_net_u32(0x02000000 + n_pfxs);
6089
6090 fei = fib_table_entry_path_add2(0,
6091 &pfx_r[n_pfxs],
6092 FIB_SOURCE_API,
6093 FIB_ENTRY_FLAG_NONE,
6094 r_paths);
6095
Neale Ranns2303cb12018-02-21 04:57:17 -08006096 FIB_TEST(!fib_test_validate_entry(fei,
6097 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6098 1,
6099 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006100 "recursive via high preference paths");
6101
6102 /*
6103 * withdraw hig pref resolving entry
6104 */
6105 fib_table_entry_delete(0,
6106 &pfx_1_1_1_1_s_32,
6107 FIB_SOURCE_API);
6108
6109 /* suspend so the update walk kicks int */
6110 vlib_process_suspend(vlib_get_main(), 1e-5);
6111
Neale Ranns2303cb12018-02-21 04:57:17 -08006112 FIB_TEST(!fib_test_validate_entry(fei,
6113 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6114 1,
6115 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006116 "recursive via medium preference paths");
6117
6118 /*
6119 * withdraw medium pref resolving entry
6120 */
6121 fib_table_entry_delete(0,
6122 &pfx_1_1_1_2_s_32,
6123 FIB_SOURCE_API);
6124
6125 /* suspend so the update walk kicks int */
6126 vlib_process_suspend(vlib_get_main(), 1e-5);
6127
Neale Ranns2303cb12018-02-21 04:57:17 -08006128 FIB_TEST(!fib_test_validate_entry(fei,
6129 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6130 1,
6131 &ip_o_1_1_1_3),
Neale Ranns57b58602017-07-15 07:37:25 -07006132 "recursive via low preference paths");
6133
6134 /*
6135 * add back paths for next iteration
6136 */
6137 fei = fib_table_entry_update(0,
6138 &pfx_1_1_1_2_s_32,
6139 FIB_SOURCE_API,
6140 FIB_ENTRY_FLAG_NONE,
6141 nr_paths);
6142 fei = fib_table_entry_update(0,
6143 &pfx_1_1_1_1_s_32,
6144 FIB_SOURCE_API,
6145 FIB_ENTRY_FLAG_NONE,
6146 nr_paths);
6147
6148 /* suspend so the update walk kicks int */
6149 vlib_process_suspend(vlib_get_main(), 1e-5);
6150
6151 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
Neale Ranns2303cb12018-02-21 04:57:17 -08006152 FIB_TEST(!fib_test_validate_entry(fei,
6153 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6154 1,
6155 &ip_o_1_1_1_1),
Neale Ranns57b58602017-07-15 07:37:25 -07006156 "recursive via high preference paths");
6157 }
6158
6159
6160 fib_table_entry_delete(0,
6161 &pfx_1_1_1_1_s_32,
6162 FIB_SOURCE_API);
6163
6164 /* suspend so the update walk kicks int */
6165 vlib_process_suspend(vlib_get_main(), 1e-5);
6166
6167 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6168 {
6169 fei = fib_table_lookup_exact_match(0, &pfx_r[n_pfxs]);
6170
Neale Ranns2303cb12018-02-21 04:57:17 -08006171 FIB_TEST(!fib_test_validate_entry(fei,
6172 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6173 1,
6174 &ip_o_1_1_1_2),
Neale Ranns57b58602017-07-15 07:37:25 -07006175 "recursive via medium preference paths");
6176 }
6177 for (n_pfxs = 0; n_pfxs < N_PFXS; n_pfxs++)
6178 {
6179 fib_table_entry_delete(0,
6180 &pfx_r[n_pfxs],
6181 FIB_SOURCE_API);
6182 }
6183
6184 /*
6185 * Cleanup
6186 */
6187 fib_table_entry_delete(0,
6188 &pfx_1_1_1_2_s_32,
6189 FIB_SOURCE_API);
6190 fib_table_entry_delete(0,
6191 &pfx_1_1_1_3_s_32,
6192 FIB_SOURCE_API);
6193
6194 dpo_reset(&ip_1_1_1_1);
6195 dpo_reset(&ip_1_1_1_2);
6196 dpo_reset(&ip_1_1_1_3);
6197 adj_unlock(ai_low_2);
6198 adj_unlock(ai_low_1);
6199 adj_unlock(ai_med_2);
6200 adj_unlock(ai_med_1);
6201 adj_unlock(ai_hi_2);
6202 adj_unlock(ai_hi_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08006203
6204 return (res);
Neale Ranns57b58602017-07-15 07:37:25 -07006205}
Neale Rannsad422ed2016-11-02 14:20:04 +00006206
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006207/*
6208 * Test the recursive route route handling for GRE tunnels
6209 */
Neale Ranns0ebe8d72016-12-08 19:48:11 +00006210static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006211fib_test_label (void)
6212{
6213 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;
6214 const u32 fib_index = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -08006215 int lb_count, ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006216 test_main_t *tm;
6217 ip4_main_t *im;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006218
Neale Ranns2303cb12018-02-21 04:57:17 -08006219 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006220 lb_count = pool_elts(load_balance_pool);
6221 tm = &test_main;
6222 im = &ip4_main;
6223
6224 /*
6225 * add interface routes. We'll assume this works. It's more rigorously
6226 * tested elsewhere.
6227 */
6228 fib_prefix_t local0_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006229 .fp_len = 24,
6230 .fp_proto = FIB_PROTOCOL_IP4,
6231 .fp_addr = {
6232 .ip4 = {
6233 /* 10.10.10.10 */
6234 .as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
6235 },
6236 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006237 };
6238
6239 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08006240 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006241
6242 vec_validate(im->fib_index_by_sw_if_index, tm->hw[0]->sw_if_index);
6243 im->fib_index_by_sw_if_index[tm->hw[0]->sw_if_index] = fib_index;
6244
6245 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006246 FIB_SOURCE_INTERFACE,
6247 (FIB_ENTRY_FLAG_CONNECTED |
6248 FIB_ENTRY_FLAG_ATTACHED),
6249 DPO_PROTO_IP4,
6250 NULL,
6251 tm->hw[0]->sw_if_index,
6252 ~0,
6253 1,
6254 NULL,
6255 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006256 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6257 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006258 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006259
6260 local0_pfx.fp_len = 32;
6261 fib_table_entry_update_one_path(fib_index, &local0_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006262 FIB_SOURCE_INTERFACE,
6263 (FIB_ENTRY_FLAG_CONNECTED |
6264 FIB_ENTRY_FLAG_LOCAL),
6265 DPO_PROTO_IP4,
6266 NULL,
6267 tm->hw[0]->sw_if_index,
6268 ~0, // invalid fib index
6269 1,
6270 NULL,
6271 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006272 fei = fib_table_lookup_exact_match(fib_index, &local0_pfx);
6273
6274 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006275 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006276
6277 fib_prefix_t local1_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006278 .fp_len = 24,
6279 .fp_proto = FIB_PROTOCOL_IP4,
6280 .fp_addr = {
6281 .ip4 = {
6282 /* 10.10.11.10 */
6283 .as_u32 = clib_host_to_net_u32(0x0a0a0b0a),
6284 },
6285 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006286 };
6287
6288 vec_validate(im->fib_index_by_sw_if_index, tm->hw[1]->sw_if_index);
6289 im->fib_index_by_sw_if_index[tm->hw[1]->sw_if_index] = fib_index;
6290
6291 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006292 FIB_SOURCE_INTERFACE,
6293 (FIB_ENTRY_FLAG_CONNECTED |
6294 FIB_ENTRY_FLAG_ATTACHED),
6295 DPO_PROTO_IP4,
6296 NULL,
6297 tm->hw[1]->sw_if_index,
6298 ~0,
6299 1,
6300 NULL,
6301 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006302 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6303 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006304 "attached interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006305
6306 local1_pfx.fp_len = 32;
6307 fib_table_entry_update_one_path(fib_index, &local1_pfx,
Neale Ranns2303cb12018-02-21 04:57:17 -08006308 FIB_SOURCE_INTERFACE,
6309 (FIB_ENTRY_FLAG_CONNECTED |
6310 FIB_ENTRY_FLAG_LOCAL),
6311 DPO_PROTO_IP4,
6312 NULL,
6313 tm->hw[1]->sw_if_index,
6314 ~0, // invalid fib index
6315 1,
6316 NULL,
6317 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006318 fei = fib_table_lookup_exact_match(fib_index, &local1_pfx);
6319
6320 FIB_TEST((FIB_NODE_INDEX_INVALID != fei),
Neale Ranns2303cb12018-02-21 04:57:17 -08006321 "local interface route present");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006322
6323 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006324 .ip4 = {
6325 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
6326 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006327 };
6328 ip46_address_t nh_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006329 .ip4 = {
6330 .as_u32 = clib_host_to_net_u32(0x0a0a0b01),
6331 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006332 };
6333 ip46_address_t nh_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006334 .ip4 = {
6335 .as_u32 = clib_host_to_net_u32(0x0a0a0b02),
6336 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006337 };
6338
6339 ai_v4_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006340 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006341 &nh_10_10_11_1,
6342 tm->hw[1]->sw_if_index);
6343 ai_v4_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006344 VNET_LINK_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006345 &nh_10_10_11_2,
6346 tm->hw[1]->sw_if_index);
6347 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006348 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006349 &nh_10_10_10_1,
6350 tm->hw[0]->sw_if_index);
6351 ai_mpls_10_10_11_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006352 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006353 &nh_10_10_11_2,
6354 tm->hw[1]->sw_if_index);
6355 ai_mpls_10_10_11_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
Neale Ranns924d03a2016-10-19 08:25:46 +01006356 VNET_LINK_MPLS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006357 &nh_10_10_11_1,
6358 tm->hw[1]->sw_if_index);
6359
6360 /*
6361 * Add an etry with one path with a real out-going label
6362 */
6363 fib_prefix_t pfx_1_1_1_1_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006364 .fp_len = 32,
6365 .fp_proto = FIB_PROTOCOL_IP4,
6366 .fp_addr = {
6367 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
6368 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006369 };
6370 fib_test_lb_bucket_t l99_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006371 .type = FT_LB_LABEL_O_ADJ,
6372 .label_o_adj = {
6373 .adj = ai_mpls_10_10_10_1,
6374 .label = 99,
6375 .eos = MPLS_EOS,
6376 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006377 };
6378 fib_test_lb_bucket_t l99_neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006379 .type = FT_LB_LABEL_O_ADJ,
6380 .label_o_adj = {
6381 .adj = ai_mpls_10_10_10_1,
6382 .label = 99,
6383 .eos = MPLS_NON_EOS,
6384 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006385 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006386 fib_mpls_label_t *l99 = NULL, fml99 = {
6387 .fml_value = 99,
6388 };
6389 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006390
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006391 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006392 &pfx_1_1_1_1_s_32,
6393 FIB_SOURCE_API,
6394 FIB_ENTRY_FLAG_NONE,
6395 DPO_PROTO_IP4,
6396 &nh_10_10_10_1,
6397 tm->hw[0]->sw_if_index,
6398 ~0, // invalid fib index
6399 1,
6400 l99,
6401 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006402
6403 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
6404 FIB_TEST((FIB_NODE_INDEX_INVALID != fei), "1.1.1.1/32 created");
6405
Neale Ranns2303cb12018-02-21 04:57:17 -08006406 FIB_TEST(!fib_test_validate_entry(fei,
6407 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6408 1,
6409 &l99_eos_o_10_10_10_1),
6410 "1.1.1.1/32 LB 1 bucket via label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006411
6412 /*
6413 * add a path with an implicit NULL label
6414 */
6415 fib_test_lb_bucket_t a_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006416 .type = FT_LB_ADJ,
6417 .adj = {
6418 .adj = ai_v4_10_10_11_1,
6419 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006420 };
6421 fib_test_lb_bucket_t a_mpls_o_10_10_11_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006422 .type = FT_LB_ADJ,
6423 .adj = {
6424 .adj = ai_mpls_10_10_11_1,
6425 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006426 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006427 fib_mpls_label_t *l_imp_null = NULL, fml_imp_null = {
6428 .fml_value = MPLS_IETF_IMPLICIT_NULL_LABEL,
6429 };
6430 vec_add1(l_imp_null, fml_imp_null);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006431
6432 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006433 &pfx_1_1_1_1_s_32,
6434 FIB_SOURCE_API,
6435 FIB_ENTRY_FLAG_NONE,
6436 DPO_PROTO_IP4,
6437 &nh_10_10_11_1,
6438 tm->hw[1]->sw_if_index,
6439 ~0, // invalid fib index
6440 1,
6441 l_imp_null,
6442 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006443
Neale Ranns2303cb12018-02-21 04:57:17 -08006444 FIB_TEST(!fib_test_validate_entry(fei,
6445 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6446 2,
6447 &l99_eos_o_10_10_10_1,
6448 &a_o_10_10_11_1),
6449 "1.1.1.1/32 LB 2 buckets via: "
6450 "label 99 over 10.10.10.1, "
6451 "adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006452
6453 /*
6454 * assign the route a local label
6455 */
6456 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006457 &pfx_1_1_1_1_s_32,
6458 24001);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006459
6460 fib_prefix_t pfx_24001_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006461 .fp_proto = FIB_PROTOCOL_MPLS,
6462 .fp_label = 24001,
6463 .fp_eos = MPLS_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006464 };
6465 fib_prefix_t pfx_24001_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006466 .fp_proto = FIB_PROTOCOL_MPLS,
6467 .fp_label = 24001,
6468 .fp_eos = MPLS_NON_EOS,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006469 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006470 fib_test_lb_bucket_t disp_o_10_10_11_1 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006471 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006472 .adj = {
6473 .adj = ai_v4_10_10_11_1,
6474 },
6475 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006476
6477 /*
6478 * The EOS entry should link to both the paths,
6479 * and use an ip adj for the imp-null
6480 * The NON-EOS entry should link to both the paths,
6481 * and use an mpls adj for the imp-null
6482 */
6483 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006484 &pfx_24001_eos);
6485 FIB_TEST(!fib_test_validate_entry(fei,
6486 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6487 2,
6488 &l99_eos_o_10_10_10_1,
6489 &disp_o_10_10_11_1),
6490 "24001/eos LB 2 buckets via: "
6491 "label 99 over 10.10.10.1, "
6492 "mpls disp adj over 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006493
6494
6495 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006496 &pfx_24001_neos);
6497 FIB_TEST(!fib_test_validate_entry(fei,
6498 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6499 2,
6500 &l99_neos_o_10_10_10_1,
6501 &a_mpls_o_10_10_11_1),
6502 "24001/neos LB 1 bucket via: "
6503 "label 99 over 10.10.10.1 ",
6504 "mpls-adj via 10.10.11.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006505
6506 /*
6507 * add an unlabelled path, this is excluded from the neos chains,
6508 */
6509 fib_test_lb_bucket_t adj_o_10_10_11_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006510 .type = FT_LB_ADJ,
6511 .adj = {
6512 .adj = ai_v4_10_10_11_2,
6513 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006514 };
Neale Ranns62fe07c2017-10-31 12:28:22 -07006515 fib_test_lb_bucket_t disp_o_10_10_11_2 = {
Neale Ranns31ed7442018-02-23 05:29:09 -08006516 .type = FT_LB_MPLS_DISP_PIPE_O_ADJ,
Neale Ranns62fe07c2017-10-31 12:28:22 -07006517 .adj = {
6518 .adj = ai_v4_10_10_11_2,
6519 },
6520 };
6521
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006522
6523 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006524 &pfx_1_1_1_1_s_32,
6525 FIB_SOURCE_API,
6526 FIB_ENTRY_FLAG_NONE,
6527 DPO_PROTO_IP4,
6528 &nh_10_10_11_2,
6529 tm->hw[1]->sw_if_index,
6530 ~0, // invalid fib index
6531 1,
6532 NULL,
6533 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006534
Neale Ranns2303cb12018-02-21 04:57:17 -08006535 FIB_TEST(!fib_test_validate_entry(fei,
6536 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6537 16, // 3 choices spread over 16 buckets
6538 &l99_eos_o_10_10_10_1,
6539 &l99_eos_o_10_10_10_1,
6540 &l99_eos_o_10_10_10_1,
6541 &l99_eos_o_10_10_10_1,
6542 &l99_eos_o_10_10_10_1,
6543 &l99_eos_o_10_10_10_1,
6544 &a_o_10_10_11_1,
6545 &a_o_10_10_11_1,
6546 &a_o_10_10_11_1,
6547 &a_o_10_10_11_1,
6548 &a_o_10_10_11_1,
6549 &adj_o_10_10_11_2,
6550 &adj_o_10_10_11_2,
6551 &adj_o_10_10_11_2,
6552 &adj_o_10_10_11_2,
6553 &adj_o_10_10_11_2),
6554 "1.1.1.1/32 LB 16 buckets via: "
6555 "label 99 over 10.10.10.1, "
6556 "adj over 10.10.11.1",
6557 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006558
6559 /*
6560 * get and lock a reference to the non-eos of the via entry 1.1.1.1/32
6561 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006562 dpo_id_t non_eos_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006563 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006564 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6565 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006566
6567 /*
6568 * n-eos has only the 2 labelled paths
6569 */
6570 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006571 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006572
Neale Ranns2303cb12018-02-21 04:57:17 -08006573 FIB_TEST(!fib_test_validate_entry(fei,
6574 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6575 2,
6576 &l99_neos_o_10_10_10_1,
6577 &a_mpls_o_10_10_11_1),
6578 "24001/neos LB 2 buckets via: "
6579 "label 99 over 10.10.10.1, "
6580 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006581
6582 /*
6583 * A labelled recursive
6584 */
6585 fib_prefix_t pfx_2_2_2_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006586 .fp_len = 32,
6587 .fp_proto = FIB_PROTOCOL_IP4,
6588 .fp_addr = {
6589 .ip4.as_u32 = clib_host_to_net_u32(0x02020202),
6590 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006591 };
6592 fib_test_lb_bucket_t l1600_eos_o_1_1_1_1 = {
6593 .type = FT_LB_LABEL_O_LB,
6594 .label_o_lb = {
6595 .lb = non_eos_1_1_1_1.dpoi_index,
6596 .label = 1600,
6597 .eos = MPLS_EOS,
Neale Ranns31ed7442018-02-23 05:29:09 -08006598 .mode = FIB_MPLS_LSP_MODE_UNIFORM,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006599 },
6600 };
Neale Ranns31ed7442018-02-23 05:29:09 -08006601 fib_mpls_label_t *l1600 = NULL, fml1600 = {
6602 .fml_value = 1600,
6603 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
6604 };
6605 vec_add1(l1600, fml1600);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006606
Neale Ranns31ed7442018-02-23 05:29:09 -08006607 fei = fib_table_entry_update_one_path(fib_index,
6608 &pfx_2_2_2_2_s_32,
6609 FIB_SOURCE_API,
6610 FIB_ENTRY_FLAG_NONE,
6611 DPO_PROTO_IP4,
6612 &pfx_1_1_1_1_s_32.fp_addr,
6613 ~0,
6614 fib_index,
6615 1,
6616 l1600,
6617 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006618
Neale Ranns2303cb12018-02-21 04:57:17 -08006619 FIB_TEST(!fib_test_validate_entry(fei,
6620 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6621 1,
6622 &l1600_eos_o_1_1_1_1),
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006623 "2.2.2.2.2/32 LB 1 buckets via: "
6624 "label 1600 over 1.1.1.1");
6625
Neale Ranns948e00f2016-10-20 13:39:34 +01006626 dpo_id_t dpo_44 = DPO_INVALID;
Neale Ranns3ee44042016-10-03 13:05:48 +01006627 index_t urpfi;
6628
6629 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_UNICAST_IP4, &dpo_44);
6630 urpfi = load_balance_get_urpf(dpo_44.dpoi_index);
6631
6632 FIB_TEST(fib_urpf_check(urpfi, tm->hw[0]->sw_if_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006633 "uRPF check for 2.2.2.2/32 on %d OK",
6634 tm->hw[0]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006635 FIB_TEST(fib_urpf_check(urpfi, tm->hw[1]->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[1]->sw_if_index);
Neale Ranns3ee44042016-10-03 13:05:48 +01006638 FIB_TEST(!fib_urpf_check(urpfi, 99),
Neale Ranns2303cb12018-02-21 04:57:17 -08006639 "uRPF check for 2.2.2.2/32 on 99 not-OK",
6640 99);
Neale Ranns3ee44042016-10-03 13:05:48 +01006641
6642 fib_entry_contribute_forwarding(fei, FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS, &dpo_44);
6643 FIB_TEST(urpfi == load_balance_get_urpf(dpo_44.dpoi_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08006644 "Shared uRPF on IP and non-EOS chain");
Neale Ranns3ee44042016-10-03 13:05:48 +01006645
6646 dpo_reset(&dpo_44);
6647
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006648 /*
6649 * we are holding a lock on the non-eos LB of the via-entry.
6650 * do a PIC-core failover by shutting the link of the via-entry.
6651 *
6652 * shut down the link with the valid label
6653 */
6654 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006655 tm->hw[0]->sw_if_index,
6656 0);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006657
6658 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006659 FIB_TEST(!fib_test_validate_entry(fei,
6660 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6661 2,
6662 &a_o_10_10_11_1,
6663 &adj_o_10_10_11_2),
6664 "1.1.1.1/32 LB 2 buckets via: "
6665 "adj over 10.10.11.1, ",
6666 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006667
6668 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006669 &pfx_24001_eos);
6670 FIB_TEST(!fib_test_validate_entry(fei,
6671 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6672 2,
6673 &disp_o_10_10_11_1,
6674 &disp_o_10_10_11_2),
6675 "24001/eos LB 2 buckets via: "
6676 "mpls-disp adj over 10.10.11.1, ",
6677 "mpls-disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006678
6679 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006680 &pfx_24001_neos);
6681 FIB_TEST(!fib_test_validate_entry(fei,
6682 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6683 1,
6684 &a_mpls_o_10_10_11_1),
6685 "24001/neos LB 1 buckets via: "
6686 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006687
6688 /*
6689 * test that the pre-failover load-balance has been in-place
6690 * modified
6691 */
Neale Ranns948e00f2016-10-20 13:39:34 +01006692 dpo_id_t current = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006693 fib_entry_contribute_forwarding(fei,
Neale Ranns2303cb12018-02-21 04:57:17 -08006694 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6695 &current);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006696
6697 FIB_TEST(!dpo_cmp(&non_eos_1_1_1_1,
6698 &current),
Neale Ranns2303cb12018-02-21 04:57:17 -08006699 "PIC-core LB inplace modified %U %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006700 format_dpo_id, &non_eos_1_1_1_1, 0,
6701 format_dpo_id, &current, 0);
6702
6703 dpo_reset(&non_eos_1_1_1_1);
6704 dpo_reset(&current);
6705
6706 /*
6707 * no-shut the link with the valid label
6708 */
6709 vnet_sw_interface_set_flags(vnet_get_main(),
Neale Ranns2303cb12018-02-21 04:57:17 -08006710 tm->hw[0]->sw_if_index,
6711 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006712
6713 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006714 FIB_TEST(!fib_test_validate_entry(fei,
6715 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6716 16, // 3 choices spread over 16 buckets
6717 &l99_eos_o_10_10_10_1,
6718 &l99_eos_o_10_10_10_1,
6719 &l99_eos_o_10_10_10_1,
6720 &l99_eos_o_10_10_10_1,
6721 &l99_eos_o_10_10_10_1,
6722 &l99_eos_o_10_10_10_1,
6723 &a_o_10_10_11_1,
6724 &a_o_10_10_11_1,
6725 &a_o_10_10_11_1,
6726 &a_o_10_10_11_1,
6727 &a_o_10_10_11_1,
6728 &adj_o_10_10_11_2,
6729 &adj_o_10_10_11_2,
6730 &adj_o_10_10_11_2,
6731 &adj_o_10_10_11_2,
6732 &adj_o_10_10_11_2),
6733 "1.1.1.1/32 LB 16 buckets via: "
6734 "label 99 over 10.10.10.1, "
6735 "adj over 10.10.11.1",
6736 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006737
6738
6739 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006740 &pfx_24001_eos);
6741 FIB_TEST(!fib_test_validate_entry(fei,
6742 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6743 16, // 3 choices spread over 16 buckets
6744 &l99_eos_o_10_10_10_1,
6745 &l99_eos_o_10_10_10_1,
6746 &l99_eos_o_10_10_10_1,
6747 &l99_eos_o_10_10_10_1,
6748 &l99_eos_o_10_10_10_1,
6749 &l99_eos_o_10_10_10_1,
6750 &disp_o_10_10_11_1,
6751 &disp_o_10_10_11_1,
6752 &disp_o_10_10_11_1,
6753 &disp_o_10_10_11_1,
6754 &disp_o_10_10_11_1,
6755 &disp_o_10_10_11_2,
6756 &disp_o_10_10_11_2,
6757 &disp_o_10_10_11_2,
6758 &disp_o_10_10_11_2,
6759 &disp_o_10_10_11_2),
6760 "24001/eos LB 16 buckets via: "
6761 "label 99 over 10.10.10.1, "
6762 "MPLS disp adj over 10.10.11.1",
6763 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006764
6765 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006766 &pfx_24001_neos);
6767 FIB_TEST(!fib_test_validate_entry(fei,
6768 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6769 2,
6770 &l99_neos_o_10_10_10_1,
6771 &a_mpls_o_10_10_11_1),
6772 "24001/neos LB 2 buckets via: "
6773 "label 99 over 10.10.10.1, "
6774 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006775
6776 /*
6777 * remove the first path with the valid label
6778 */
6779 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006780 &pfx_1_1_1_1_s_32,
6781 FIB_SOURCE_API,
6782 DPO_PROTO_IP4,
6783 &nh_10_10_10_1,
6784 tm->hw[0]->sw_if_index,
6785 ~0, // invalid fib index
6786 1,
6787 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006788
6789 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006790 FIB_TEST(!fib_test_validate_entry(fei,
6791 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6792 2,
6793 &a_o_10_10_11_1,
6794 &adj_o_10_10_11_2),
6795 "1.1.1.1/32 LB 2 buckets via: "
6796 "adj over 10.10.11.1, "
6797 "adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006798
6799 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006800 &pfx_24001_eos);
6801 FIB_TEST(!fib_test_validate_entry(fei,
6802 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6803 2,
6804 &disp_o_10_10_11_1,
6805 &disp_o_10_10_11_2),
6806 "24001/eos LB 2 buckets via: "
6807 "MPLS disp adj over 10.10.11.1, "
6808 "MPLS disp adj-v4 over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006809
6810 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006811 &pfx_24001_neos);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006812
Neale Ranns2303cb12018-02-21 04:57:17 -08006813 FIB_TEST(!fib_test_validate_entry(fei,
6814 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6815 1,
6816 &a_mpls_o_10_10_11_1),
6817 "24001/neos LB 1 buckets via: "
6818 "adj-mpls over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006819
6820 /*
6821 * remove the other path with a valid label
6822 */
6823 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006824 .type = FT_LB_DROP,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006825 };
Neale Rannsf12a83f2017-04-18 09:09:40 -07006826 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006827 .type = FT_LB_DROP,
6828 .special = {
6829 .adj = DPO_PROTO_MPLS,
6830 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07006831 };
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006832
6833 fib_table_entry_path_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006834 &pfx_1_1_1_1_s_32,
6835 FIB_SOURCE_API,
6836 DPO_PROTO_IP4,
6837 &nh_10_10_11_1,
6838 tm->hw[1]->sw_if_index,
6839 ~0, // invalid fib index
6840 1,
6841 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006842
6843 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006844 FIB_TEST(!fib_test_validate_entry(fei,
6845 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6846 1,
6847 &adj_o_10_10_11_2),
6848 "1.1.1.1/32 LB 1 buckets via: "
6849 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006850
6851 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006852 &pfx_24001_eos);
6853 FIB_TEST(!fib_test_validate_entry(fei,
6854 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6855 1,
6856 &disp_o_10_10_11_2),
6857 "24001/eos LB 1 buckets via: "
6858 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006859
6860 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006861 &pfx_24001_neos);
6862 FIB_TEST(!fib_test_validate_entry(fei,
6863 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6864 1,
6865 &mpls_bucket_drop),
6866 "24001/neos LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006867
6868 /*
6869 * add back the path with the valid label
6870 */
Neale Rannsad422ed2016-11-02 14:20:04 +00006871 l99 = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08006872 vec_add1(l99, fml99);
Neale Rannsad422ed2016-11-02 14:20:04 +00006873
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006874 fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006875 &pfx_1_1_1_1_s_32,
6876 FIB_SOURCE_API,
6877 FIB_ENTRY_FLAG_NONE,
6878 DPO_PROTO_IP4,
6879 &nh_10_10_10_1,
6880 tm->hw[0]->sw_if_index,
6881 ~0, // invalid fib index
6882 1,
6883 l99,
6884 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006885
6886 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006887 FIB_TEST(!fib_test_validate_entry(fei,
6888 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6889 2,
6890 &l99_eos_o_10_10_10_1,
6891 &adj_o_10_10_11_2),
6892 "1.1.1.1/32 LB 2 buckets via: "
6893 "label 99 over 10.10.10.1, "
6894 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006895
6896 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006897 &pfx_24001_eos);
6898 FIB_TEST(!fib_test_validate_entry(fei,
6899 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6900 2,
6901 &l99_eos_o_10_10_10_1,
6902 &disp_o_10_10_11_2),
6903 "24001/eos LB 2 buckets via: "
6904 "label 99 over 10.10.10.1, "
6905 "MPLS disp adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006906
6907 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006908 &pfx_24001_neos);
6909 FIB_TEST(!fib_test_validate_entry(fei,
6910 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6911 1,
6912 &l99_neos_o_10_10_10_1),
6913 "24001/neos LB 1 buckets via: "
6914 "label 99 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006915
6916 /*
Neale Ranns1357f3b2016-10-16 12:01:42 -07006917 * change the local label
6918 */
6919 fib_table_entry_local_label_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006920 &pfx_1_1_1_1_s_32,
6921 25005);
Neale Ranns1357f3b2016-10-16 12:01:42 -07006922
6923 fib_prefix_t pfx_25005_eos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006924 .fp_proto = FIB_PROTOCOL_MPLS,
6925 .fp_label = 25005,
6926 .fp_eos = MPLS_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006927 };
6928 fib_prefix_t pfx_25005_neos = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006929 .fp_proto = FIB_PROTOCOL_MPLS,
6930 .fp_label = 25005,
6931 .fp_eos = MPLS_NON_EOS,
Neale Ranns1357f3b2016-10-16 12:01:42 -07006932 };
6933
6934 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006935 fib_table_lookup(fib_index, &pfx_24001_eos)),
6936 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006937 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006938 fib_table_lookup(fib_index, &pfx_24001_neos)),
6939 "24001/eos removed after label change");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006940
6941 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006942 &pfx_25005_eos);
6943 FIB_TEST(!fib_test_validate_entry(fei,
6944 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
6945 2,
6946 &l99_eos_o_10_10_10_1,
6947 &disp_o_10_10_11_2),
6948 "25005/eos LB 2 buckets via: "
6949 "label 99 over 10.10.10.1, "
6950 "MPLS disp adj over 10.10.11.2");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006951
6952 fei = fib_table_lookup(MPLS_FIB_DEFAULT_TABLE_ID,
Neale Ranns2303cb12018-02-21 04:57:17 -08006953 &pfx_25005_neos);
6954 FIB_TEST(!fib_test_validate_entry(fei,
6955 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
6956 1,
6957 &l99_neos_o_10_10_10_1),
6958 "25005/neos LB 1 buckets via: "
6959 "label 99 over 10.10.10.1");
Neale Ranns1357f3b2016-10-16 12:01:42 -07006960
6961 /*
6962 * remove the local label.
6963 * the check that the MPLS entries are gone is done by the fact the
6964 * MPLS table is no longer present.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006965 */
6966 fib_table_entry_local_label_remove(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08006967 &pfx_1_1_1_1_s_32,
6968 25005);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006969
6970 fei = fib_table_lookup(fib_index, &pfx_1_1_1_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08006971 FIB_TEST(!fib_test_validate_entry(fei,
6972 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
6973 2,
6974 &l99_eos_o_10_10_10_1,
6975 &adj_o_10_10_11_2),
6976 "24001/eos LB 2 buckets via: "
6977 "label 99 over 10.10.10.1, "
6978 "adj over 10.10.11.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006979
6980 FIB_TEST((FIB_NODE_INDEX_INVALID ==
Neale Ranns2303cb12018-02-21 04:57:17 -08006981 mpls_fib_index_from_table_id(MPLS_FIB_DEFAULT_TABLE_ID)),
6982 "No more MPLS FIB entries => table removed");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006983
6984 /*
6985 * add another via-entry for the recursive
6986 */
6987 fib_prefix_t pfx_1_1_1_2_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006988 .fp_len = 32,
6989 .fp_proto = FIB_PROTOCOL_IP4,
6990 .fp_addr = {
6991 .ip4.as_u32 = clib_host_to_net_u32(0x01010102),
6992 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01006993 };
6994 fib_test_lb_bucket_t l101_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08006995 .type = FT_LB_LABEL_O_ADJ,
6996 .label_o_adj = {
6997 .adj = ai_mpls_10_10_10_1,
6998 .label = 101,
6999 .eos = MPLS_EOS,
7000 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007001 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007002 fib_mpls_label_t *l101 = NULL, fml101 = {
7003 .fml_value = 101,
7004 };
7005 vec_add1(l101, fml101);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007006
7007 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007008 &pfx_1_1_1_2_s_32,
7009 FIB_SOURCE_API,
7010 FIB_ENTRY_FLAG_NONE,
7011 DPO_PROTO_IP4,
7012 &nh_10_10_10_1,
7013 tm->hw[0]->sw_if_index,
7014 ~0, // invalid fib index
7015 1,
7016 l101,
7017 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007018
Neale Ranns2303cb12018-02-21 04:57:17 -08007019 FIB_TEST(!fib_test_validate_entry(fei,
7020 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7021 1,
7022 &l101_eos_o_10_10_10_1),
7023 "1.1.1.2/32 LB 1 buckets via: "
7024 "label 101 over 10.10.10.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007025
Neale Ranns948e00f2016-10-20 13:39:34 +01007026 dpo_id_t non_eos_1_1_1_2 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007027 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007028 &pfx_1_1_1_1_s_32),
7029 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7030 &non_eos_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007031 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007032 &pfx_1_1_1_2_s_32),
7033 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
7034 &non_eos_1_1_1_2);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007035
7036 fib_test_lb_bucket_t l1601_eos_o_1_1_1_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007037 .type = FT_LB_LABEL_O_LB,
7038 .label_o_lb = {
7039 .lb = non_eos_1_1_1_2.dpoi_index,
7040 .label = 1601,
7041 .eos = MPLS_EOS,
7042 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007043 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007044 fib_mpls_label_t *l1601 = NULL, fml1601 = {
7045 .fml_value = 1601,
7046 };
7047 vec_add1(l1601, fml1601);
Neale Rannsad422ed2016-11-02 14:20:04 +00007048
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007049 l1600_eos_o_1_1_1_1.label_o_lb.lb = non_eos_1_1_1_1.dpoi_index;
7050
7051 fei = fib_table_entry_path_add(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007052 &pfx_2_2_2_2_s_32,
7053 FIB_SOURCE_API,
7054 FIB_ENTRY_FLAG_NONE,
7055 DPO_PROTO_IP4,
7056 &pfx_1_1_1_2_s_32.fp_addr,
7057 ~0,
7058 fib_index,
7059 1,
7060 l1601,
7061 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007062
Neale Ranns2303cb12018-02-21 04:57:17 -08007063 FIB_TEST(!fib_test_validate_entry(fei,
7064 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7065 2,
7066 &l1600_eos_o_1_1_1_1,
7067 &l1601_eos_o_1_1_1_2),
7068 "2.2.2.2/32 LB 2 buckets via: "
7069 "label 1600 via 1.1,1.1, "
7070 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007071
7072 /*
7073 * update the via-entry so it no longer has an imp-null path.
7074 * the LB for the recursive can use an imp-null
7075 */
Neale Rannsad422ed2016-11-02 14:20:04 +00007076 l_imp_null = NULL;
Neale Ranns31ed7442018-02-23 05:29:09 -08007077 vec_add1(l_imp_null, fml_imp_null);
Neale Rannsad422ed2016-11-02 14:20:04 +00007078
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007079 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007080 &pfx_1_1_1_2_s_32,
7081 FIB_SOURCE_API,
7082 FIB_ENTRY_FLAG_NONE,
7083 DPO_PROTO_IP4,
7084 &nh_10_10_11_1,
7085 tm->hw[1]->sw_if_index,
7086 ~0, // invalid fib index
7087 1,
7088 l_imp_null,
7089 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007090
Neale Ranns2303cb12018-02-21 04:57:17 -08007091 FIB_TEST(!fib_test_validate_entry(fei,
7092 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7093 1,
7094 &a_o_10_10_11_1),
7095 "1.1.1.2/32 LB 1 buckets via: "
7096 "adj 10.10.11.1");
7097
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007098 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007099 FIB_TEST(!fib_test_validate_entry(fei,
7100 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7101 2,
7102 &l1600_eos_o_1_1_1_1,
7103 &l1601_eos_o_1_1_1_2),
7104 "2.2.2.2/32 LB 2 buckets via: "
7105 "label 1600 via 1.1,1.1, "
7106 "label 16001 via 1.1.1.2");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007107
7108 /*
7109 * update the via-entry so it no longer has labelled paths.
7110 * the LB for the recursive should exclue this via form its LB
7111 */
7112 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007113 &pfx_1_1_1_2_s_32,
7114 FIB_SOURCE_API,
7115 FIB_ENTRY_FLAG_NONE,
7116 DPO_PROTO_IP4,
7117 &nh_10_10_11_1,
7118 tm->hw[1]->sw_if_index,
7119 ~0, // invalid fib index
7120 1,
7121 NULL,
7122 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007123
Neale Ranns2303cb12018-02-21 04:57:17 -08007124 FIB_TEST(!fib_test_validate_entry(fei,
7125 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7126 1,
7127 &a_o_10_10_11_1),
7128 "1.1.1.2/32 LB 1 buckets via: "
7129 "adj 10.10.11.1");
7130
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007131 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007132 FIB_TEST(!fib_test_validate_entry(fei,
7133 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7134 1,
7135 &l1600_eos_o_1_1_1_1),
7136 "2.2.2.2/32 LB 1 buckets via: "
7137 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007138
7139 dpo_reset(&non_eos_1_1_1_1);
7140 dpo_reset(&non_eos_1_1_1_2);
7141
7142 /*
7143 * Add a recursive with no out-labels. We expect to use the IP of the via
7144 */
7145 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007146 .fp_len = 32,
7147 .fp_proto = FIB_PROTOCOL_IP4,
7148 .fp_addr = {
7149 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
7150 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007151 };
Neale Ranns948e00f2016-10-20 13:39:34 +01007152 dpo_id_t ip_1_1_1_1 = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007153
7154 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007155 &pfx_2_2_2_3_s_32,
7156 FIB_SOURCE_API,
7157 FIB_ENTRY_FLAG_NONE,
7158 DPO_PROTO_IP4,
7159 &pfx_1_1_1_1_s_32.fp_addr,
7160 ~0,
7161 fib_index,
7162 1,
7163 NULL,
7164 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007165
7166 fib_entry_contribute_forwarding(fib_table_lookup(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007167 &pfx_1_1_1_1_s_32),
7168 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7169 &ip_1_1_1_1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007170
7171 fib_test_lb_bucket_t ip_o_1_1_1_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007172 .type = FT_LB_O_LB,
7173 .lb = {
7174 .lb = ip_1_1_1_1.dpoi_index,
7175 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007176 };
7177
7178 fei = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007179 FIB_TEST(!fib_test_validate_entry(fei,
7180 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7181 1,
7182 &ip_o_1_1_1_1),
7183 "2.2.2.2.3/32 LB 1 buckets via: "
7184 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007185
7186 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08007187 * Add a recursive with an imp-null out-label.
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007188 * We expect to use the IP of the via
7189 */
7190 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007191 .fp_len = 32,
7192 .fp_proto = FIB_PROTOCOL_IP4,
7193 .fp_addr = {
7194 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
7195 },
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007196 };
7197
7198 fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007199 &pfx_2_2_2_4_s_32,
7200 FIB_SOURCE_API,
7201 FIB_ENTRY_FLAG_NONE,
7202 DPO_PROTO_IP4,
7203 &pfx_1_1_1_1_s_32.fp_addr,
7204 ~0,
7205 fib_index,
7206 1,
7207 NULL,
7208 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007209
7210 fei = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007211 FIB_TEST(!fib_test_validate_entry(fei,
7212 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7213 1,
7214 &ip_o_1_1_1_1),
7215 "2.2.2.2.4/32 LB 1 buckets via: "
7216 "ip 1.1.1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007217
7218 dpo_reset(&ip_1_1_1_1);
7219
7220 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00007221 * Create an entry with a deep label stack
7222 */
7223 fib_prefix_t pfx_2_2_5_5_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007224 .fp_len = 32,
7225 .fp_proto = FIB_PROTOCOL_IP4,
7226 .fp_addr = {
7227 .ip4.as_u32 = clib_host_to_net_u32(0x02020505),
7228 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007229 };
7230 fib_test_lb_bucket_t ls_eos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08007231 .type = FT_LB_LABEL_STACK_O_ADJ,
7232 .label_stack_o_adj = {
7233 .adj = ai_mpls_10_10_11_1,
7234 .label_stack_size = 8,
7235 .label_stack = {
7236 200, 201, 202, 203, 204, 205, 206, 207
7237 },
7238 .eos = MPLS_EOS,
7239 },
Neale Rannsad422ed2016-11-02 14:20:04 +00007240 };
Neale Ranns31ed7442018-02-23 05:29:09 -08007241 fib_mpls_label_t *label_stack = NULL;
Neale Rannsad422ed2016-11-02 14:20:04 +00007242 vec_validate(label_stack, 7);
7243 for (ii = 0; ii < 8; ii++)
7244 {
Neale Ranns31ed7442018-02-23 05:29:09 -08007245 label_stack[ii].fml_value = ii + 200;
Neale Rannsad422ed2016-11-02 14:20:04 +00007246 }
7247
7248 fei = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007249 &pfx_2_2_5_5_s_32,
7250 FIB_SOURCE_API,
7251 FIB_ENTRY_FLAG_NONE,
7252 DPO_PROTO_IP4,
7253 &nh_10_10_11_1,
7254 tm->hw[1]->sw_if_index,
7255 ~0, // invalid fib index
7256 1,
7257 label_stack,
7258 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00007259
Neale Ranns2303cb12018-02-21 04:57:17 -08007260 FIB_TEST(!fib_test_validate_entry(fei,
7261 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7262 1,
7263 &ls_eos_o_10_10_10_1),
7264 "2.2.5.5/32 LB 1 buckets via: "
7265 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00007266 fib_table_entry_delete_index(fei, FIB_SOURCE_API);
7267
7268 /*
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007269 * cleanup
7270 */
7271 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007272 &pfx_1_1_1_2_s_32,
7273 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007274
7275 fei = fib_table_lookup(fib_index, &pfx_2_2_2_2_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007276 FIB_TEST(!fib_test_validate_entry(fei,
7277 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7278 1,
7279 &l1600_eos_o_1_1_1_1),
7280 "2.2.2.2/32 LB 1 buckets via: "
7281 "label 1600 via 1.1,1.1");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007282
7283 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007284 &pfx_1_1_1_1_s_32,
7285 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007286
Neale Ranns2303cb12018-02-21 04:57:17 -08007287 FIB_TEST(!fib_test_validate_entry(fei,
7288 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7289 1,
7290 &bucket_drop),
7291 "2.2.2.2/32 LB 1 buckets via: DROP");
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007292
7293 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007294 &pfx_2_2_2_2_s_32,
7295 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007296 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007297 &pfx_2_2_2_3_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_4_s_32,
7301 FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007302
7303 adj_unlock(ai_mpls_10_10_10_1);
7304 adj_unlock(ai_mpls_10_10_11_2);
7305 adj_unlock(ai_v4_10_10_11_1);
7306 adj_unlock(ai_v4_10_10_11_2);
7307 adj_unlock(ai_mpls_10_10_11_1);
7308
7309 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08007310 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007311
7312 local0_pfx.fp_len = 32;
7313 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007314 &local0_pfx,
7315 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007316 local0_pfx.fp_len = 24;
7317 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007318 &local0_pfx,
7319 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007320 local1_pfx.fp_len = 32;
7321 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007322 &local1_pfx,
7323 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007324 local1_pfx.fp_len = 24;
7325 fib_table_entry_delete(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08007326 &local1_pfx,
7327 FIB_SOURCE_INTERFACE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007328
7329 /*
7330 * +1 for the drop LB in the MPLS tables.
7331 */
7332 FIB_TEST(lb_count+1 == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08007333 "Load-balance resources freed %d of %d",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007334 lb_count+1, pool_elts(load_balance_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007335
Neale Ranns2303cb12018-02-21 04:57:17 -08007336 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007337}
7338
7339#define N_TEST_CHILDREN 4
7340#define PARENT_INDEX 0
7341
7342typedef struct fib_node_test_t_
7343{
7344 fib_node_t node;
7345 u32 sibling;
7346 u32 index;
7347 fib_node_back_walk_ctx_t *ctxs;
7348 u32 destroyed;
7349} fib_node_test_t;
7350
7351static fib_node_test_t fib_test_nodes[N_TEST_CHILDREN+1];
7352
7353#define PARENT() (&fib_test_nodes[PARENT_INDEX].node)
7354
Neale Ranns2303cb12018-02-21 04:57:17 -08007355#define FOR_EACH_TEST_CHILD(_tc) \
7356 for (ii = 1, (_tc) = &fib_test_nodes[1]; \
7357 ii < N_TEST_CHILDREN+1; \
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007358 ii++, (_tc) = &fib_test_nodes[ii])
7359
7360static fib_node_t *
7361fib_test_child_get_node (fib_node_index_t index)
7362{
7363 return (&fib_test_nodes[index].node);
7364}
7365
7366static int fib_test_walk_spawns_walks;
7367
7368static fib_node_back_walk_rc_t
7369fib_test_child_back_walk_notify (fib_node_t *node,
7370 fib_node_back_walk_ctx_t *ctx)
7371{
7372 fib_node_test_t *tc = (fib_node_test_t*) node;
7373
7374 vec_add1(tc->ctxs, *ctx);
7375
7376 if (1 == fib_test_walk_spawns_walks)
7377 fib_walk_sync(FIB_NODE_TYPE_TEST, tc->index, ctx);
7378 if (2 == fib_test_walk_spawns_walks)
7379 fib_walk_async(FIB_NODE_TYPE_TEST, tc->index,
7380 FIB_WALK_PRIORITY_HIGH, ctx);
7381
7382 return (FIB_NODE_BACK_WALK_CONTINUE);
7383}
7384
7385static void
7386fib_test_child_last_lock_gone (fib_node_t *node)
7387{
7388 fib_node_test_t *tc = (fib_node_test_t *)node;
7389
7390 tc->destroyed = 1;
7391}
7392
7393/**
7394 * The FIB walk's graph node virtual function table
7395 */
7396static const fib_node_vft_t fib_test_child_vft = {
7397 .fnv_get = fib_test_child_get_node,
7398 .fnv_last_lock = fib_test_child_last_lock_gone,
7399 .fnv_back_walk = fib_test_child_back_walk_notify,
7400};
7401
7402/*
7403 * the function (that should have been static but isn't so I can do this)
7404 * that processes the walk from the async queue,
7405 */
7406f64 fib_walk_process_queues(vlib_main_t * vm,
7407 const f64 quota);
7408u32 fib_walk_queue_get_size(fib_walk_priority_t prio);
7409
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007410static int
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007411fib_test_walk (void)
7412{
7413 fib_node_back_walk_ctx_t high_ctx = {}, low_ctx = {};
7414 fib_node_test_t *tc;
7415 vlib_main_t *vm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007416 u32 ii, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007417
Neale Ranns2303cb12018-02-21 04:57:17 -08007418 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007419 vm = vlib_get_main();
7420 fib_node_register_type(FIB_NODE_TYPE_TEST, &fib_test_child_vft);
7421
7422 /*
7423 * init a fake node on which we will add children
7424 */
7425 fib_node_init(&fib_test_nodes[PARENT_INDEX].node,
7426 FIB_NODE_TYPE_TEST);
7427
7428 FOR_EACH_TEST_CHILD(tc)
7429 {
7430 fib_node_init(&tc->node, FIB_NODE_TYPE_TEST);
7431 fib_node_lock(&tc->node);
7432 tc->ctxs = NULL;
7433 tc->index = ii;
7434 tc->sibling = fib_node_child_add(FIB_NODE_TYPE_TEST,
7435 PARENT_INDEX,
7436 FIB_NODE_TYPE_TEST, ii);
7437 }
7438
7439 /*
7440 * enqueue a walk across the parents children.
7441 */
Neale Ranns450cd302016-11-09 17:49:42 +00007442 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007443
7444 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7445 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7446 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7447 "Parent has %d children pre-walk",
7448 fib_node_list_get_size(PARENT()->fn_children));
7449
7450 /*
7451 * give the walk a large amount of time so it gets to the end
7452 */
7453 fib_walk_process_queues(vm, 1);
7454
7455 FOR_EACH_TEST_CHILD(tc)
7456 {
7457 FIB_TEST(1 == vec_len(tc->ctxs),
7458 "%d child visitsed %d times",
7459 ii, vec_len(tc->ctxs));
7460 vec_free(tc->ctxs);
7461 }
7462 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7463 "Queue is empty post walk");
7464 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7465 "Parent has %d children post walk",
7466 fib_node_list_get_size(PARENT()->fn_children));
7467
7468 /*
7469 * walk again. should be no increase in the number of visits, since
7470 * the walk will have terminated.
7471 */
7472 fib_walk_process_queues(vm, 1);
7473
7474 FOR_EACH_TEST_CHILD(tc)
7475 {
7476 FIB_TEST(0 == vec_len(tc->ctxs),
7477 "%d child visitsed %d times",
7478 ii, vec_len(tc->ctxs));
7479 }
7480
7481 /*
7482 * schedule a low and hig priority walk. expect the high to be performed
7483 * before the low.
7484 * schedule the high prio walk first so that it is further from the head
7485 * of the dependency list. that way it won't merge with the low one.
7486 */
7487 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7488 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7489
7490 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7491 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7492 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7493 FIB_WALK_PRIORITY_LOW, &low_ctx);
7494
7495 fib_walk_process_queues(vm, 1);
7496
7497 FOR_EACH_TEST_CHILD(tc)
7498 {
7499 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7500 "%d child visitsed by high prio walk", ii);
7501 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7502 "%d child visitsed by low prio walk", ii);
7503 vec_free(tc->ctxs);
7504 }
7505 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7506 "Queue is empty post prio walk");
7507 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7508 "Parent has %d children post prio walk",
7509 fib_node_list_get_size(PARENT()->fn_children));
7510
7511 /*
7512 * schedule 2 walks of the same priority that can be megred.
7513 * expect that each child is thus visited only once.
7514 */
7515 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7516 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7517
7518 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7519 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7520 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7521 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7522
7523 fib_walk_process_queues(vm, 1);
7524
7525 FOR_EACH_TEST_CHILD(tc)
7526 {
7527 FIB_TEST(1 == vec_len(tc->ctxs),
7528 "%d child visitsed %d times during merge walk",
7529 ii, vec_len(tc->ctxs));
7530 vec_free(tc->ctxs);
7531 }
7532 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7533 "Queue is empty post merge walk");
7534 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7535 "Parent has %d children post merge walk",
7536 fib_node_list_get_size(PARENT()->fn_children));
7537
7538 /*
7539 * schedule 2 walks of the same priority that cannot be megred.
7540 * expect that each child is thus visited twice and in the order
7541 * in which the walks were scheduled.
7542 */
7543 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
7544 low_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_ADJ_UPDATE;
7545
7546 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7547 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7548 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7549 FIB_WALK_PRIORITY_HIGH, &low_ctx);
7550
7551 fib_walk_process_queues(vm, 1);
7552
7553 FOR_EACH_TEST_CHILD(tc)
7554 {
7555 FIB_TEST(high_ctx.fnbw_reason == tc->ctxs[0].fnbw_reason,
7556 "%d child visitsed by high prio walk", ii);
7557 FIB_TEST(low_ctx.fnbw_reason == tc->ctxs[1].fnbw_reason,
7558 "%d child visitsed by low prio walk", ii);
7559 vec_free(tc->ctxs);
7560 }
7561 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7562 "Queue is empty post no-merge walk");
7563 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7564 "Parent has %d children post no-merge walk",
7565 fib_node_list_get_size(PARENT()->fn_children));
7566
7567 /*
7568 * schedule a walk that makes one one child progress.
7569 * we do this by giving the queue draining process zero
7570 * time quanta. it's a do..while loop, so it does something.
7571 */
Neale Ranns450cd302016-11-09 17:49:42 +00007572 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007573
7574 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7575 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7576 fib_walk_process_queues(vm, 0);
7577
7578 FOR_EACH_TEST_CHILD(tc)
7579 {
7580 if (ii == N_TEST_CHILDREN)
7581 {
7582 FIB_TEST(1 == vec_len(tc->ctxs),
7583 "%d child visitsed %d times in zero quanta walk",
7584 ii, vec_len(tc->ctxs));
7585 }
7586 else
7587 {
7588 FIB_TEST(0 == vec_len(tc->ctxs),
7589 "%d child visitsed %d times in 0 quanta walk",
7590 ii, vec_len(tc->ctxs));
7591 }
7592 }
7593 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7594 "Queue is not empty post zero quanta walk");
7595 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7596 "Parent has %d children post zero qunta walk",
7597 fib_node_list_get_size(PARENT()->fn_children));
7598
7599 /*
7600 * another one step
7601 */
7602 fib_walk_process_queues(vm, 0);
7603
7604 FOR_EACH_TEST_CHILD(tc)
7605 {
7606 if (ii >= N_TEST_CHILDREN-1)
7607 {
7608 FIB_TEST(1 == vec_len(tc->ctxs),
7609 "%d child visitsed %d times in 2nd zero quanta walk",
7610 ii, vec_len(tc->ctxs));
7611 }
7612 else
7613 {
7614 FIB_TEST(0 == vec_len(tc->ctxs),
7615 "%d child visitsed %d times in 2nd 0 quanta walk",
7616 ii, vec_len(tc->ctxs));
7617 }
7618 }
7619 FIB_TEST(1 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7620 "Queue is not empty post zero quanta walk");
7621 FIB_TEST(N_TEST_CHILDREN+1 == fib_node_list_get_size(PARENT()->fn_children),
7622 "Parent has %d children post zero qunta walk",
7623 fib_node_list_get_size(PARENT()->fn_children));
7624
7625 /*
7626 * schedule another walk that will catch-up and merge.
7627 */
7628 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7629 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7630 fib_walk_process_queues(vm, 1);
7631
7632 FOR_EACH_TEST_CHILD(tc)
7633 {
7634 if (ii >= N_TEST_CHILDREN-1)
7635 {
7636 FIB_TEST(2 == vec_len(tc->ctxs),
7637 "%d child visitsed %d times in 2nd zero quanta merge walk",
7638 ii, vec_len(tc->ctxs));
7639 vec_free(tc->ctxs);
7640 }
7641 else
7642 {
7643 FIB_TEST(1 == vec_len(tc->ctxs),
7644 "%d child visitsed %d times in 2nd 0 quanta merge walk",
7645 ii, vec_len(tc->ctxs));
7646 vec_free(tc->ctxs);
7647 }
7648 }
7649 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7650 "Queue is not empty post 2nd zero quanta merge walk");
7651 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7652 "Parent has %d children post 2nd zero qunta merge walk",
7653 fib_node_list_get_size(PARENT()->fn_children));
7654
7655 /*
7656 * park a async walk in the middle of the list, then have an sync walk catch
7657 * it. same expectations as async catches async.
7658 */
Neale Ranns450cd302016-11-09 17:49:42 +00007659 high_ctx.fnbw_reason = FIB_NODE_BW_REASON_FLAG_RESOLVE;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007660
7661 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7662 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7663
7664 fib_walk_process_queues(vm, 0);
7665 fib_walk_process_queues(vm, 0);
7666
7667 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7668
7669 FOR_EACH_TEST_CHILD(tc)
7670 {
7671 if (ii >= N_TEST_CHILDREN-1)
7672 {
7673 FIB_TEST(2 == vec_len(tc->ctxs),
7674 "%d child visitsed %d times in sync catches async walk",
7675 ii, vec_len(tc->ctxs));
7676 vec_free(tc->ctxs);
7677 }
7678 else
7679 {
7680 FIB_TEST(1 == vec_len(tc->ctxs),
7681 "%d child visitsed %d times in sync catches async walk",
7682 ii, vec_len(tc->ctxs));
7683 vec_free(tc->ctxs);
7684 }
7685 }
7686 FIB_TEST(0 == fib_walk_queue_get_size(FIB_WALK_PRIORITY_HIGH),
7687 "Queue is not empty post 2nd zero quanta merge walk");
7688 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7689 "Parent has %d children post 2nd zero qunta merge walk",
7690 fib_node_list_get_size(PARENT()->fn_children));
7691
7692 /*
7693 * make the parent a child of one of its children, thus inducing a routing loop.
7694 */
7695 fib_test_nodes[PARENT_INDEX].sibling =
7696 fib_node_child_add(FIB_NODE_TYPE_TEST,
7697 1, // the first child
7698 FIB_NODE_TYPE_TEST,
7699 PARENT_INDEX);
7700
7701 /*
7702 * execute a sync walk from the parent. each child visited spawns more sync
7703 * walks. we expect the walk to terminate.
7704 */
7705 fib_test_walk_spawns_walks = 1;
7706
7707 fib_walk_sync(FIB_NODE_TYPE_TEST, PARENT_INDEX, &high_ctx);
7708
7709 FOR_EACH_TEST_CHILD(tc)
7710 {
7711 /*
7712 * child 1 - which is last in the list - has the loop.
7713 * the other children a re thus visitsed first. the we meet
7714 * child 1. we go round the loop again, visting the other children.
7715 * then we meet the walk in the dep list and bail. child 1 is not visitsed
7716 * again.
7717 */
7718 if (1 == ii)
7719 {
7720 FIB_TEST(1 == vec_len(tc->ctxs),
7721 "child %d visitsed %d times during looped sync walk",
7722 ii, vec_len(tc->ctxs));
7723 }
7724 else
7725 {
7726 FIB_TEST(2 == vec_len(tc->ctxs),
7727 "child %d visitsed %d times during looped sync walk",
7728 ii, vec_len(tc->ctxs));
7729 }
7730 vec_free(tc->ctxs);
7731 }
7732 FIB_TEST(N_TEST_CHILDREN == fib_node_list_get_size(PARENT()->fn_children),
7733 "Parent has %d children post sync loop walk",
7734 fib_node_list_get_size(PARENT()->fn_children));
7735
7736 /*
7737 * the walk doesn't reach the max depth because the infra knows that sync
7738 * meets sync implies a loop and bails early.
7739 */
7740 FIB_TEST(high_ctx.fnbw_depth == 9,
7741 "Walk context depth %d post sync loop walk",
7742 high_ctx.fnbw_depth);
7743
7744 /*
7745 * execute an async walk of the graph loop, with each child spawns sync walks
7746 */
7747 high_ctx.fnbw_depth = 0;
7748 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7749 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7750
7751 fib_walk_process_queues(vm, 1);
7752
7753 FOR_EACH_TEST_CHILD(tc)
7754 {
7755 /*
7756 * we don't really care how many times the children are visisted, as long as
7757 * it is more than once.
7758 */
7759 FIB_TEST(1 <= vec_len(tc->ctxs),
7760 "child %d visitsed %d times during looped aync spawns sync walk",
7761 ii, vec_len(tc->ctxs));
7762 vec_free(tc->ctxs);
7763 }
7764
7765 /*
7766 * execute an async walk of the graph loop, with each child spawns async walks
7767 */
7768 fib_test_walk_spawns_walks = 2;
7769 high_ctx.fnbw_depth = 0;
7770 fib_walk_async(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7771 FIB_WALK_PRIORITY_HIGH, &high_ctx);
7772
7773 fib_walk_process_queues(vm, 1);
7774
7775 FOR_EACH_TEST_CHILD(tc)
7776 {
7777 /*
7778 * we don't really care how many times the children are visisted, as long as
7779 * it is more than once.
7780 */
7781 FIB_TEST(1 <= vec_len(tc->ctxs),
7782 "child %d visitsed %d times during looped async spawns async walk",
7783 ii, vec_len(tc->ctxs));
Neale Ranns2303cb12018-02-21 04:57:17 -08007784 vec_free(tc->ctxs);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007785 }
7786
7787
7788 fib_node_child_remove(FIB_NODE_TYPE_TEST,
7789 1, // the first child
7790 fib_test_nodes[PARENT_INDEX].sibling);
7791
7792 /*
7793 * cleanup
7794 */
7795 FOR_EACH_TEST_CHILD(tc)
7796 {
7797 fib_node_child_remove(FIB_NODE_TYPE_TEST, PARENT_INDEX,
7798 tc->sibling);
7799 fib_node_deinit(&tc->node);
7800 fib_node_unlock(&tc->node);
7801 }
7802 fib_node_deinit(PARENT());
7803
7804 /*
7805 * The parent will be destroyed when the last lock on it goes.
7806 * this test ensures all the walk objects are unlocking it.
7807 */
7808 FIB_TEST((1 == fib_test_nodes[PARENT_INDEX].destroyed),
7809 "Parent was destroyed");
Neale Ranns0ebe8d72016-12-08 19:48:11 +00007810
Neale Ranns2303cb12018-02-21 04:57:17 -08007811 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01007812}
7813
Neale Ranns88fc83e2017-04-05 08:11:14 -07007814/*
7815 * declaration of the otherwise static callback functions
7816 */
7817void fib_bfd_notify (bfd_listen_event_e event,
7818 const bfd_session_t *session);
7819void adj_bfd_notify (bfd_listen_event_e event,
7820 const bfd_session_t *session);
7821
7822/**
7823 * Test BFD session interaction with FIB
7824 */
7825static int
7826fib_test_bfd (void)
7827{
7828 fib_node_index_t fei;
7829 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08007830 int n_feis, res;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007831
Neale Ranns2303cb12018-02-21 04:57:17 -08007832 res = 0;
Neale Ranns88fc83e2017-04-05 08:11:14 -07007833 /* via 10.10.10.1 */
7834 ip46_address_t nh_10_10_10_1 = {
7835 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
7836 };
7837 /* via 10.10.10.2 */
7838 ip46_address_t nh_10_10_10_2 = {
7839 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
7840 };
7841 /* via 10.10.10.10 */
7842 ip46_address_t nh_10_10_10_10 = {
7843 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a0a),
7844 };
7845 n_feis = fib_entry_pool_size();
7846
7847 tm = &test_main;
7848
7849 /*
7850 * add interface routes. we'll assume this works. it's tested elsewhere
7851 */
7852 fib_prefix_t pfx_10_10_10_10_s_24 = {
7853 .fp_len = 24,
7854 .fp_proto = FIB_PROTOCOL_IP4,
7855 .fp_addr = nh_10_10_10_10,
7856 };
7857
7858 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_24,
7859 FIB_SOURCE_INTERFACE,
7860 (FIB_ENTRY_FLAG_CONNECTED |
7861 FIB_ENTRY_FLAG_ATTACHED),
Neale Rannsda78f952017-05-24 09:15:43 -07007862 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007863 NULL,
7864 tm->hw[0]->sw_if_index,
7865 ~0, // invalid fib index
7866 1, // weight
7867 NULL,
7868 FIB_ROUTE_PATH_FLAG_NONE);
7869
7870 fib_prefix_t pfx_10_10_10_10_s_32 = {
7871 .fp_len = 32,
7872 .fp_proto = FIB_PROTOCOL_IP4,
7873 .fp_addr = nh_10_10_10_10,
7874 };
7875 fib_table_entry_update_one_path(0, &pfx_10_10_10_10_s_32,
7876 FIB_SOURCE_INTERFACE,
7877 (FIB_ENTRY_FLAG_CONNECTED |
7878 FIB_ENTRY_FLAG_LOCAL),
Neale Rannsda78f952017-05-24 09:15:43 -07007879 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07007880 NULL,
7881 tm->hw[0]->sw_if_index,
7882 ~0, // invalid fib index
7883 1, // weight
7884 NULL,
7885 FIB_ROUTE_PATH_FLAG_NONE);
7886
7887 /*
7888 * A BFD session via a neighbour we do not yet know
7889 */
7890 bfd_session_t bfd_10_10_10_1 = {
7891 .udp = {
7892 .key = {
7893 .fib_index = 0,
7894 .peer_addr = nh_10_10_10_1,
7895 },
7896 },
7897 .hop_type = BFD_HOP_TYPE_MULTI,
7898 .local_state = BFD_STATE_init,
7899 };
7900
7901 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7902
7903 /*
7904 * A new entry will be created that forwards via the adj
7905 */
7906 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
7907 VNET_LINK_IP4,
7908 &nh_10_10_10_1,
7909 tm->hw[0]->sw_if_index);
7910 fib_prefix_t pfx_10_10_10_1_s_32 = {
7911 .fp_addr = nh_10_10_10_1,
7912 .fp_len = 32,
7913 .fp_proto = FIB_PROTOCOL_IP4,
7914 };
7915 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
7916 .type = FT_LB_ADJ,
7917 .adj = {
7918 .adj = ai_10_10_10_1,
7919 },
7920 };
7921
7922 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007923 FIB_TEST(!fib_test_validate_entry(fei,
7924 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7925 1,
7926 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007927 "BFD sourced %U via %U",
7928 format_fib_prefix, &pfx_10_10_10_1_s_32,
7929 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7930
7931 /*
7932 * Delete the BFD session. Expect the fib_entry to be removed
7933 */
7934 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7935
7936 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
7937 FIB_TEST(FIB_NODE_INDEX_INVALID == fei,
7938 "BFD sourced %U removed",
7939 format_fib_prefix, &pfx_10_10_10_1_s_32);
7940
7941 /*
7942 * Add the BFD source back
7943 */
7944 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7945
7946 /*
7947 * source the entry via the ADJ fib
7948 */
Neale Ranns81424992017-05-18 03:03:22 -07007949 fei = fib_table_entry_path_add(0,
7950 &pfx_10_10_10_1_s_32,
7951 FIB_SOURCE_ADJ,
7952 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007953 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007954 &nh_10_10_10_1,
7955 tm->hw[0]->sw_if_index,
7956 ~0, // invalid fib index
7957 1,
7958 NULL,
7959 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007960
7961 /*
7962 * Delete the BFD session. Expect the fib_entry to remain
7963 */
7964 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
7965
7966 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08007967 FIB_TEST(!fib_test_validate_entry(fei,
7968 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
7969 1,
7970 &adj_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07007971 "BFD sourced %U remains via %U",
7972 format_fib_prefix, &pfx_10_10_10_1_s_32,
7973 format_ip_adjacency, ai_10_10_10_1, FORMAT_IP_ADJACENCY_NONE);
7974
7975 /*
7976 * Add the BFD source back
7977 */
7978 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
7979
7980 /*
7981 * Create another ADJ FIB
7982 */
7983 fib_prefix_t pfx_10_10_10_2_s_32 = {
7984 .fp_addr = nh_10_10_10_2,
7985 .fp_len = 32,
7986 .fp_proto = FIB_PROTOCOL_IP4,
7987 };
Neale Ranns81424992017-05-18 03:03:22 -07007988 fib_table_entry_path_add(0,
7989 &pfx_10_10_10_2_s_32,
7990 FIB_SOURCE_ADJ,
7991 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07007992 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07007993 &nh_10_10_10_2,
7994 tm->hw[0]->sw_if_index,
7995 ~0, // invalid fib index
7996 1,
7997 NULL,
7998 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07007999 /*
8000 * A BFD session for the new ADJ FIB
8001 */
8002 bfd_session_t bfd_10_10_10_2 = {
8003 .udp = {
8004 .key = {
8005 .fib_index = 0,
8006 .peer_addr = nh_10_10_10_2,
8007 },
8008 },
8009 .hop_type = BFD_HOP_TYPE_MULTI,
8010 .local_state = BFD_STATE_init,
8011 };
8012
8013 fib_bfd_notify (BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_2);
8014
8015 /*
8016 * remove the adj-fib source whilst the session is present
8017 * then add it back
8018 */
8019 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
Neale Ranns81424992017-05-18 03:03:22 -07008020 fib_table_entry_path_add(0,
8021 &pfx_10_10_10_2_s_32,
8022 FIB_SOURCE_ADJ,
8023 FIB_ENTRY_FLAG_ATTACHED,
Neale Rannsda78f952017-05-24 09:15:43 -07008024 DPO_PROTO_IP4,
Neale Ranns81424992017-05-18 03:03:22 -07008025 &nh_10_10_10_2,
8026 tm->hw[0]->sw_if_index,
8027 ~0, // invalid fib index
8028 1,
8029 NULL,
8030 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008031
8032 /*
8033 * Before adding a recursive via the BFD tracked ADJ-FIBs,
8034 * bring one of the sessions UP, leave the other down
8035 */
8036 bfd_10_10_10_1.local_state = BFD_STATE_up;
8037 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8038 bfd_10_10_10_2.local_state = BFD_STATE_down;
8039 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8040
8041 /*
8042 * A recursive prefix via both of the ADJ FIBs
8043 */
8044 fib_prefix_t pfx_200_0_0_0_s_24 = {
8045 .fp_proto = FIB_PROTOCOL_IP4,
8046 .fp_len = 32,
8047 .fp_addr = {
8048 .ip4.as_u32 = clib_host_to_net_u32(0xc8000000),
8049 },
8050 };
8051 const dpo_id_t *dpo_10_10_10_1, *dpo_10_10_10_2;
8052
8053 dpo_10_10_10_1 =
8054 fib_entry_contribute_ip_forwarding(
8055 fib_table_lookup_exact_match(0, &pfx_10_10_10_1_s_32));
8056 dpo_10_10_10_2 =
8057 fib_entry_contribute_ip_forwarding(
8058 fib_table_lookup_exact_match(0, &pfx_10_10_10_2_s_32));
8059
8060 fib_test_lb_bucket_t lb_o_10_10_10_1 = {
8061 .type = FT_LB_O_LB,
8062 .lb = {
8063 .lb = dpo_10_10_10_1->dpoi_index,
8064 },
8065 };
8066 fib_test_lb_bucket_t lb_o_10_10_10_2 = {
8067 .type = FT_LB_O_LB,
8068 .lb = {
8069 .lb = dpo_10_10_10_2->dpoi_index,
8070 },
8071 };
8072
8073 /*
8074 * A prefix via the adj-fib that is BFD down => DROP
8075 */
8076 fei = fib_table_entry_path_add(0,
8077 &pfx_200_0_0_0_s_24,
8078 FIB_SOURCE_API,
8079 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008080 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008081 &nh_10_10_10_2,
8082 ~0, // recursive
8083 0, // default fib index
8084 1,
8085 NULL,
8086 FIB_ROUTE_PATH_FLAG_NONE);
8087 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8088 "%U resolves via drop",
8089 format_fib_prefix, &pfx_200_0_0_0_s_24);
8090
8091 /*
8092 * add a path via the UP BFD adj-fib.
8093 * we expect that the DOWN BFD ADJ FIB is not used.
8094 */
8095 fei = fib_table_entry_path_add(0,
8096 &pfx_200_0_0_0_s_24,
8097 FIB_SOURCE_API,
8098 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008099 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008100 &nh_10_10_10_1,
8101 ~0, // recursive
8102 0, // default fib index
8103 1,
8104 NULL,
8105 FIB_ROUTE_PATH_FLAG_NONE);
8106
Neale Ranns2303cb12018-02-21 04:57:17 -08008107 FIB_TEST(!fib_test_validate_entry(fei,
8108 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8109 1,
8110 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008111 "Recursive %U only UP BFD adj-fibs",
8112 format_fib_prefix, &pfx_200_0_0_0_s_24);
8113
8114 /*
8115 * Send a BFD state change to UP - both sessions are now up
8116 * the recursive prefix should LB over both
8117 */
8118 bfd_10_10_10_2.local_state = BFD_STATE_up;
8119 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8120
8121
Neale Ranns2303cb12018-02-21 04:57:17 -08008122 FIB_TEST(!fib_test_validate_entry(fei,
8123 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8124 2,
8125 &lb_o_10_10_10_1,
8126 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008127 "Recursive %U via both UP BFD adj-fibs",
8128 format_fib_prefix, &pfx_200_0_0_0_s_24);
8129
8130 /*
8131 * Send a BFD state change to DOWN
8132 * the recursive prefix should exclude the down
8133 */
8134 bfd_10_10_10_2.local_state = BFD_STATE_down;
8135 fib_bfd_notify (BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_2);
8136
8137
Neale Ranns2303cb12018-02-21 04:57:17 -08008138 FIB_TEST(!fib_test_validate_entry(fei,
8139 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8140 1,
8141 &lb_o_10_10_10_1),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008142 "Recursive %U via only UP",
8143 format_fib_prefix, &pfx_200_0_0_0_s_24);
8144
8145 /*
8146 * Delete the BFD session while it is in the DOWN state.
8147 * FIB should consider the entry's state as back up
8148 */
8149 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_2);
8150
Neale Ranns2303cb12018-02-21 04:57:17 -08008151 FIB_TEST(!fib_test_validate_entry(fei,
8152 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8153 2,
8154 &lb_o_10_10_10_1,
8155 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008156 "Recursive %U via both UP BFD adj-fibs post down session delete",
8157 format_fib_prefix, &pfx_200_0_0_0_s_24);
8158
8159 /*
8160 * Delete the BFD other session while it is in the UP state.
8161 */
8162 fib_bfd_notify (BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8163
Neale Ranns2303cb12018-02-21 04:57:17 -08008164 FIB_TEST(!fib_test_validate_entry(fei,
8165 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8166 2,
8167 &lb_o_10_10_10_1,
8168 &lb_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008169 "Recursive %U via both UP BFD adj-fibs post up session delete",
8170 format_fib_prefix, &pfx_200_0_0_0_s_24);
8171
8172 /*
8173 * cleaup
8174 */
8175 fib_table_entry_delete(0, &pfx_200_0_0_0_s_24, FIB_SOURCE_API);
8176 fib_table_entry_delete(0, &pfx_10_10_10_1_s_32, FIB_SOURCE_ADJ);
8177 fib_table_entry_delete(0, &pfx_10_10_10_2_s_32, FIB_SOURCE_ADJ);
8178
8179 fib_table_entry_delete(0, &pfx_10_10_10_10_s_32, FIB_SOURCE_INTERFACE);
8180 fib_table_entry_delete(0, &pfx_10_10_10_10_s_24, FIB_SOURCE_INTERFACE);
8181
8182 adj_unlock(ai_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008183 /*
Neale Ranns88fc83e2017-04-05 08:11:14 -07008184 * test no-one left behind
8185 */
8186 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8187 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
8188
8189 /*
8190 * Single-hop BFD tests
8191 */
8192 bfd_10_10_10_1.hop_type = BFD_HOP_TYPE_SINGLE;
8193 bfd_10_10_10_1.udp.key.sw_if_index = tm->hw[0]->sw_if_index;
8194
8195 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfd_10_10_10_1);
8196
8197 ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8198 VNET_LINK_IP4,
8199 &nh_10_10_10_1,
8200 tm->hw[0]->sw_if_index);
8201 /*
8202 * whilst the BFD session is not signalled, the adj is up
8203 */
Neale Ranns4faab212018-07-16 06:12:33 -07008204 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on uninit session");
Neale Ranns88fc83e2017-04-05 08:11:14 -07008205
8206 /*
8207 * bring the BFD session up
8208 */
8209 bfd_10_10_10_1.local_state = BFD_STATE_up;
8210 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8211 FIB_TEST(adj_is_up(ai_10_10_10_1), "Adj state up on UP session");
8212
8213 /*
8214 * bring the BFD session down
8215 */
8216 bfd_10_10_10_1.local_state = BFD_STATE_down;
8217 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
8218 FIB_TEST(!adj_is_up(ai_10_10_10_1), "Adj state down on DOWN session");
8219
Neale Ranns88fc83e2017-04-05 08:11:14 -07008220 /*
8221 * add an attached next hop FIB entry via the down adj
8222 */
8223 fib_prefix_t pfx_5_5_5_5_s_32 = {
8224 .fp_addr = {
8225 .ip4 = {
8226 .as_u32 = clib_host_to_net_u32(0x05050505),
8227 },
8228 },
8229 .fp_len = 32,
8230 .fp_proto = FIB_PROTOCOL_IP4,
8231 };
8232
8233 fei = fib_table_entry_path_add(0,
8234 &pfx_5_5_5_5_s_32,
8235 FIB_SOURCE_CLI,
8236 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008237 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008238 &nh_10_10_10_1,
8239 tm->hw[0]->sw_if_index,
8240 ~0, // invalid fib index
8241 1,
8242 NULL,
8243 FIB_ROUTE_PATH_FLAG_NONE);
8244 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
8245 "%U resolves via drop",
8246 format_fib_prefix, &pfx_5_5_5_5_s_32);
8247
8248 /*
8249 * Add a path via an ADJ that is up
8250 */
8251 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8252 VNET_LINK_IP4,
8253 &nh_10_10_10_2,
8254 tm->hw[0]->sw_if_index);
8255
8256 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
8257 .type = FT_LB_ADJ,
8258 .adj = {
8259 .adj = ai_10_10_10_2,
8260 },
8261 };
8262 adj_o_10_10_10_1.adj.adj = ai_10_10_10_1;
8263
8264 fei = fib_table_entry_path_add(0,
8265 &pfx_5_5_5_5_s_32,
8266 FIB_SOURCE_CLI,
8267 FIB_ENTRY_FLAG_NONE,
Neale Rannsda78f952017-05-24 09:15:43 -07008268 DPO_PROTO_IP4,
Neale Ranns88fc83e2017-04-05 08:11:14 -07008269 &nh_10_10_10_2,
8270 tm->hw[0]->sw_if_index,
8271 ~0, // invalid fib index
8272 1,
8273 NULL,
8274 FIB_ROUTE_PATH_FLAG_NONE);
8275
Neale Ranns2303cb12018-02-21 04:57:17 -08008276 FIB_TEST(!fib_test_validate_entry(fei,
8277 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8278 1,
8279 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008280 "BFD sourced %U via %U",
8281 format_fib_prefix, &pfx_5_5_5_5_s_32,
8282 format_ip_adjacency, ai_10_10_10_2, FORMAT_IP_ADJACENCY_NONE);
8283
8284 /*
8285 * Bring up the down session - should now LB
8286 */
8287 bfd_10_10_10_1.local_state = BFD_STATE_up;
8288 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfd_10_10_10_1);
Neale Ranns2303cb12018-02-21 04:57:17 -08008289 FIB_TEST(!fib_test_validate_entry(fei,
8290 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8291 2,
8292 &adj_o_10_10_10_1,
8293 &adj_o_10_10_10_2),
Neale Ranns88fc83e2017-04-05 08:11:14 -07008294 "BFD sourced %U via noth adjs",
8295 format_fib_prefix, &pfx_5_5_5_5_s_32);
8296
8297 /*
8298 * remove the BFD session state from the adj
8299 */
8300 adj_bfd_notify(BFD_LISTEN_EVENT_DELETE, &bfd_10_10_10_1);
8301
8302 /*
8303 * clean-up
8304 */
8305 fib_table_entry_delete(0, &pfx_5_5_5_5_s_32, FIB_SOURCE_CLI);
8306 adj_unlock(ai_10_10_10_1);
8307 adj_unlock(ai_10_10_10_2);
8308
8309 /*
8310 * test no-one left behind
8311 */
8312 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
8313 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -08008314
8315 return (res);
Neale Ranns88fc83e2017-04-05 08:11:14 -07008316}
8317
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008318static int
8319lfib_test (void)
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008320{
8321 const mpls_label_t deag_label = 50;
Neale Ranns2303cb12018-02-21 04:57:17 -08008322 adj_index_t ai_mpls_10_10_10_1;
Neale Ranns31ed7442018-02-23 05:29:09 -08008323 dpo_id_t dpo = DPO_INVALID;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008324 const u32 lfib_index = 0;
8325 const u32 fib_index = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008326 const dpo_id_t *dpo1;
8327 fib_node_index_t lfe;
Neale Ranns2303cb12018-02-21 04:57:17 -08008328 lookup_dpo_t *lkd;
8329 int lb_count, res;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008330 test_main_t *tm;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008331
Neale Ranns2303cb12018-02-21 04:57:17 -08008332 res = 0;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008333 tm = &test_main;
8334 lb_count = pool_elts(load_balance_pool);
8335
8336 FIB_TEST((0 == adj_nbr_db_size()), "ADJ DB size is %d",
Neale Ranns2303cb12018-02-21 04:57:17 -08008337 adj_nbr_db_size());
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008338
8339 /*
8340 * MPLS enable an interface so we get the MPLS table created
8341 */
Neale Ranns2297af02017-09-12 09:45:04 -07008342 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008343 mpls_sw_interface_enable_disable(&mpls_main,
8344 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008345 1, 1);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008346
Neale Rannsad422ed2016-11-02 14:20:04 +00008347 ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008348 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Rannsad422ed2016-11-02 14:20:04 +00008349 };
8350 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
8351 VNET_LINK_MPLS,
8352 &nh_10_10_10_1,
8353 tm->hw[0]->sw_if_index);
8354
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008355 /*
8356 * Test the specials stack properly.
8357 */
8358 fib_prefix_t exp_null_v6_pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008359 .fp_proto = FIB_PROTOCOL_MPLS,
8360 .fp_eos = MPLS_EOS,
8361 .fp_label = MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8362 .fp_payload_proto = DPO_PROTO_IP6,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008363 };
8364 lfe = fib_table_lookup(lfib_index, &exp_null_v6_pfx);
8365 FIB_TEST((FIB_NODE_INDEX_INVALID != lfe),
Neale Ranns2303cb12018-02-21 04:57:17 -08008366 "%U/%U present",
8367 format_mpls_unicast_label, MPLS_IETF_IPV6_EXPLICIT_NULL_LABEL,
8368 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008369 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008370 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8371 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008372 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8373 lkd = lookup_dpo_get(dpo1->dpoi_index);
8374
8375 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008376 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008377 format_mpls_unicast_label, deag_label,
8378 format_mpls_eos_bit, MPLS_EOS,
8379 lkd->lkd_fib_index,
8380 format_dpo_id, &dpo, 0);
8381 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8382 "%U/%U is dst deag",
8383 format_mpls_unicast_label, deag_label,
8384 format_mpls_eos_bit, MPLS_EOS);
8385 FIB_TEST((LOOKUP_TABLE_FROM_INPUT_INTERFACE == lkd->lkd_table),
8386 "%U/%U is lookup in interface's table",
8387 format_mpls_unicast_label, deag_label,
8388 format_mpls_eos_bit, MPLS_EOS);
8389 FIB_TEST((DPO_PROTO_IP6 == lkd->lkd_proto),
8390 "%U/%U is %U dst deag",
8391 format_mpls_unicast_label, deag_label,
8392 format_mpls_eos_bit, MPLS_EOS,
8393 format_dpo_proto, lkd->lkd_proto);
8394
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008395 /*
8396 * A route deag route for EOS
8397 */
8398 fib_prefix_t pfx = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008399 .fp_proto = FIB_PROTOCOL_MPLS,
8400 .fp_eos = MPLS_EOS,
8401 .fp_label = deag_label,
8402 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008403 };
Neale Ranns2303cb12018-02-21 04:57:17 -08008404 mpls_disp_dpo_t *mdd;
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008405 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008406 &pfx,
8407 FIB_SOURCE_CLI,
8408 FIB_ENTRY_FLAG_NONE,
8409 DPO_PROTO_IP4,
8410 &zero_addr,
8411 ~0,
8412 fib_index,
8413 1,
8414 NULL,
8415 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008416
8417 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008418 "%U/%U present",
8419 format_mpls_unicast_label, deag_label,
8420 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008421
8422 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008423 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8424 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008425 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
Neale Ranns31ed7442018-02-23 05:29:09 -08008426 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8427
8428 FIB_TEST((FIB_MPLS_LSP_MODE_PIPE == mdd->mdd_mode),
8429 "%U/%U disp is pipe mode",
8430 format_mpls_unicast_label, deag_label,
8431 format_mpls_eos_bit, MPLS_EOS);
8432
8433 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008434
8435 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008436 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008437 format_mpls_unicast_label, deag_label,
8438 format_mpls_eos_bit, MPLS_EOS,
8439 lkd->lkd_fib_index,
8440 format_dpo_id, &dpo, 0);
8441 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8442 "%U/%U is dst deag",
8443 format_mpls_unicast_label, deag_label,
8444 format_mpls_eos_bit, MPLS_EOS);
8445 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8446 "%U/%U is %U dst deag",
8447 format_mpls_unicast_label, deag_label,
8448 format_mpls_eos_bit, MPLS_EOS,
8449 format_dpo_proto, lkd->lkd_proto);
8450
8451 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8452
8453 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8454 &pfx)),
8455 "%U/%U not present",
8456 format_mpls_unicast_label, deag_label,
8457 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns31ed7442018-02-23 05:29:09 -08008458 dpo_reset(&dpo);
8459
8460 /*
8461 * A route deag route for EOS with LSP mode uniform
8462 */
8463 fib_mpls_label_t *l_pops = NULL, l_pop = {
8464 .fml_value = MPLS_LABEL_POP,
8465 .fml_mode = FIB_MPLS_LSP_MODE_UNIFORM,
8466 };
8467 vec_add1(l_pops, l_pop);
8468 lfe = fib_table_entry_path_add(lfib_index,
8469 &pfx,
8470 FIB_SOURCE_CLI,
8471 FIB_ENTRY_FLAG_NONE,
8472 DPO_PROTO_IP4,
8473 &zero_addr,
8474 ~0,
8475 fib_index,
8476 1,
8477 l_pops,
8478 FIB_ROUTE_PATH_FLAG_NONE);
8479
8480 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
8481 "%U/%U present",
8482 format_mpls_unicast_label, deag_label,
8483 format_mpls_eos_bit, MPLS_EOS);
8484
8485 fib_entry_contribute_forwarding(lfe,
8486 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8487 &dpo);
8488 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8489 mdd = mpls_disp_dpo_get(dpo1->dpoi_index);
8490
8491 FIB_TEST((FIB_MPLS_LSP_MODE_UNIFORM == mdd->mdd_mode),
8492 "%U/%U disp is uniform mode",
8493 format_mpls_unicast_label, deag_label,
8494 format_mpls_eos_bit, MPLS_EOS);
8495
8496 lkd = lookup_dpo_get(mdd->mdd_dpo.dpoi_index);
8497
8498 FIB_TEST((fib_index == lkd->lkd_fib_index),
8499 "%U/%U is deag in %d %U",
8500 format_mpls_unicast_label, deag_label,
8501 format_mpls_eos_bit, MPLS_EOS,
8502 lkd->lkd_fib_index,
8503 format_dpo_id, &dpo, 0);
8504 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8505 "%U/%U is dst deag",
8506 format_mpls_unicast_label, deag_label,
8507 format_mpls_eos_bit, MPLS_EOS);
8508 FIB_TEST((DPO_PROTO_IP4 == lkd->lkd_proto),
8509 "%U/%U is %U dst deag",
8510 format_mpls_unicast_label, deag_label,
8511 format_mpls_eos_bit, MPLS_EOS,
8512 format_dpo_proto, lkd->lkd_proto);
8513
8514 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8515
8516 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
8517 &pfx)),
8518 "%U/%U not present",
8519 format_mpls_unicast_label, deag_label,
8520 format_mpls_eos_bit, MPLS_EOS);
8521 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008522
8523 /*
8524 * A route deag route for non-EOS
8525 */
8526 pfx.fp_eos = MPLS_NON_EOS;
8527 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008528 &pfx,
8529 FIB_SOURCE_CLI,
8530 FIB_ENTRY_FLAG_NONE,
8531 DPO_PROTO_IP4,
8532 &zero_addr,
8533 ~0,
8534 lfib_index,
8535 1,
8536 NULL,
8537 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008538
8539 FIB_TEST((lfe == fib_table_lookup(lfib_index, &pfx)),
Neale Ranns2303cb12018-02-21 04:57:17 -08008540 "%U/%U present",
8541 format_mpls_unicast_label, deag_label,
8542 format_mpls_eos_bit, MPLS_NON_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008543
8544 fib_entry_contribute_forwarding(lfe,
Neale Ranns2303cb12018-02-21 04:57:17 -08008545 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8546 &dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008547 dpo1 = load_balance_get_bucket(dpo.dpoi_index, 0);
8548 lkd = lookup_dpo_get(dpo1->dpoi_index);
8549
8550 FIB_TEST((fib_index == lkd->lkd_fib_index),
Neale Ranns2303cb12018-02-21 04:57:17 -08008551 "%U/%U is deag in %d %U",
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008552 format_mpls_unicast_label, deag_label,
8553 format_mpls_eos_bit, MPLS_NON_EOS,
8554 lkd->lkd_fib_index,
8555 format_dpo_id, &dpo, 0);
8556 FIB_TEST((LOOKUP_INPUT_DST_ADDR == lkd->lkd_input),
8557 "%U/%U is dst deag",
8558 format_mpls_unicast_label, deag_label,
8559 format_mpls_eos_bit, MPLS_NON_EOS);
8560
8561 FIB_TEST((DPO_PROTO_MPLS == lkd->lkd_proto),
8562 "%U/%U is %U dst deag",
8563 format_mpls_unicast_label, deag_label,
8564 format_mpls_eos_bit, MPLS_NON_EOS,
8565 format_dpo_proto, lkd->lkd_proto);
8566
8567 fib_table_entry_delete_index(lfe, FIB_SOURCE_CLI);
8568
8569 FIB_TEST((FIB_NODE_INDEX_INVALID == fib_table_lookup(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008570 &pfx)),
8571 "%U/%U not present",
8572 format_mpls_unicast_label, deag_label,
8573 format_mpls_eos_bit, MPLS_EOS);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008574
Neale Rannsad422ed2016-11-02 14:20:04 +00008575 dpo_reset(&dpo);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008576
Neale Rannsad422ed2016-11-02 14:20:04 +00008577 /*
8578 * An MPLS x-connect
8579 */
8580 fib_prefix_t pfx_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008581 .fp_len = 21,
8582 .fp_proto = FIB_PROTOCOL_MPLS,
8583 .fp_label = 1200,
8584 .fp_eos = MPLS_NON_EOS,
Neale Rannsad422ed2016-11-02 14:20:04 +00008585 };
8586 fib_test_lb_bucket_t neos_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008587 .type = FT_LB_LABEL_STACK_O_ADJ,
8588 .label_stack_o_adj = {
8589 .adj = ai_mpls_10_10_10_1,
8590 .label_stack_size = 4,
8591 .label_stack = {
8592 200, 300, 400, 500,
8593 },
8594 .eos = MPLS_NON_EOS,
8595 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008596 };
8597 dpo_id_t neos_1200 = DPO_INVALID;
8598 dpo_id_t ip_1200 = DPO_INVALID;
Neale Ranns31ed7442018-02-23 05:29:09 -08008599 fib_mpls_label_t *l200 = NULL;
8600 u32 ii;
8601 for (ii = 0; ii < 4; ii++)
8602 {
8603 fib_mpls_label_t fml = {
8604 .fml_value = 200 + (ii * 100),
8605 };
8606 vec_add1(l200, fml);
8607 };
Neale Rannsad422ed2016-11-02 14:20:04 +00008608
8609 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008610 &pfx_1200,
8611 FIB_SOURCE_API,
8612 FIB_ENTRY_FLAG_NONE,
8613 DPO_PROTO_IP4,
8614 &nh_10_10_10_1,
8615 tm->hw[0]->sw_if_index,
8616 ~0, // invalid fib index
8617 1,
8618 l200,
8619 FIB_ROUTE_PATH_FLAG_NONE);
Neale Rannsad422ed2016-11-02 14:20:04 +00008620
Neale Ranns2303cb12018-02-21 04:57:17 -08008621 FIB_TEST(!fib_test_validate_entry(lfe,
8622 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8623 1,
8624 &neos_o_10_10_10_1),
8625 "1200/0 LB 1 buckets via: "
8626 "adj 10.10.11.1");
Neale Rannsad422ed2016-11-02 14:20:04 +00008627
8628 /*
8629 * A recursive route via the MPLS x-connect
8630 */
8631 fib_prefix_t pfx_2_2_2_3_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008632 .fp_len = 32,
8633 .fp_proto = FIB_PROTOCOL_IP4,
8634 .fp_addr = {
8635 .ip4.as_u32 = clib_host_to_net_u32(0x02020203),
8636 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008637 };
8638 fib_route_path_t *rpaths = NULL, rpath = {
Neale Rannsda78f952017-05-24 09:15:43 -07008639 .frp_proto = DPO_PROTO_MPLS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008640 .frp_local_label = 1200,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008641 .frp_eos = MPLS_NON_EOS,
Neale Ranns2303cb12018-02-21 04:57:17 -08008642 .frp_sw_if_index = ~0, // recurive
8643 .frp_fib_index = 0, // Default MPLS fib
8644 .frp_weight = 1,
8645 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
8646 .frp_label_stack = NULL,
Neale Rannsad422ed2016-11-02 14:20:04 +00008647 };
8648 vec_add1(rpaths, rpath);
8649
8650 fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008651 &pfx_2_2_2_3_s_32,
8652 FIB_SOURCE_API,
8653 FIB_ENTRY_FLAG_NONE,
8654 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008655
8656 /*
8657 * A labelled recursive route via the MPLS x-connect
8658 */
8659 fib_prefix_t pfx_2_2_2_4_s_32 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008660 .fp_len = 32,
8661 .fp_proto = FIB_PROTOCOL_IP4,
8662 .fp_addr = {
8663 .ip4.as_u32 = clib_host_to_net_u32(0x02020204),
8664 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008665 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008666 fib_mpls_label_t *l999 = NULL, fml_999 = {
8667 .fml_value = 999,
8668 };
8669 vec_add1(l999, fml_999);
Neale Rannsad422ed2016-11-02 14:20:04 +00008670 rpaths[0].frp_label_stack = l999,
8671
Neale Ranns2303cb12018-02-21 04:57:17 -08008672 fib_table_entry_path_add2(fib_index,
8673 &pfx_2_2_2_4_s_32,
8674 FIB_SOURCE_API,
8675 FIB_ENTRY_FLAG_NONE,
8676 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008677
8678 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008679 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8680 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008681 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008682 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8683 &neos_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008684
8685 fib_test_lb_bucket_t ip_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008686 .type = FT_LB_O_LB,
8687 .lb = {
8688 .lb = ip_1200.dpoi_index,
8689 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008690 };
8691 fib_test_lb_bucket_t mpls_o_1200 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008692 .type = FT_LB_LABEL_O_LB,
8693 .label_o_lb = {
8694 .lb = neos_1200.dpoi_index,
8695 .label = 999,
8696 .eos = MPLS_EOS,
8697 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008698 };
8699
8700 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_3_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008701 FIB_TEST(!fib_test_validate_entry(lfe,
8702 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8703 1,
8704 &ip_o_1200),
8705 "2.2.2.2.3/32 LB 1 buckets via: label 1200 EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008706 lfe = fib_table_lookup(fib_index, &pfx_2_2_2_4_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08008707 FIB_TEST(!fib_test_validate_entry(lfe,
8708 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8709 1,
8710 &mpls_o_1200),
8711 "2.2.2.2.4/32 LB 1 buckets via: label 1200 non-EOS");
Neale Rannsad422ed2016-11-02 14:20:04 +00008712
8713 fib_table_entry_delete(fib_index, &pfx_1200, FIB_SOURCE_API);
8714 fib_table_entry_delete(fib_index, &pfx_2_2_2_3_s_32, FIB_SOURCE_API);
8715 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8716
8717 dpo_reset(&neos_1200);
8718 dpo_reset(&ip_1200);
8719
8720 /*
8721 * A recursive via a label that does not exist
8722 */
8723 fib_test_lb_bucket_t bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008724 .type = FT_LB_DROP,
8725 .special = {
8726 .adj = DPO_PROTO_IP4,
8727 },
Neale Rannsf12a83f2017-04-18 09:09:40 -07008728 };
8729 fib_test_lb_bucket_t mpls_bucket_drop = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008730 .type = FT_LB_DROP,
8731 .special = {
8732 .adj = DPO_PROTO_MPLS,
8733 },
Neale Rannsad422ed2016-11-02 14:20:04 +00008734 };
8735
8736 rpaths[0].frp_label_stack = NULL;
8737 lfe = fib_table_entry_path_add2(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008738 &pfx_2_2_2_4_s_32,
8739 FIB_SOURCE_API,
8740 FIB_ENTRY_FLAG_NONE,
8741 rpaths);
Neale Rannsad422ed2016-11-02 14:20:04 +00008742
8743 fib_entry_contribute_forwarding(fib_table_lookup(fib_index, &pfx_1200),
Neale Ranns2303cb12018-02-21 04:57:17 -08008744 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8745 &ip_1200);
Neale Rannsad422ed2016-11-02 14:20:04 +00008746 ip_o_1200.lb.lb = ip_1200.dpoi_index;
8747
Neale Ranns2303cb12018-02-21 04:57:17 -08008748 FIB_TEST(!fib_test_validate_entry(lfe,
8749 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8750 1,
8751 &bucket_drop),
8752 "2.2.2.2.4/32 LB 1 buckets via: drop");
Neale Rannsad422ed2016-11-02 14:20:04 +00008753 lfe = fib_table_lookup(fib_index, &pfx_1200);
Neale Ranns2303cb12018-02-21 04:57:17 -08008754 FIB_TEST(!fib_test_validate_entry(lfe,
8755 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
8756 1,
8757 &bucket_drop),
8758 "1200/neos LB 1 buckets via: ip4-DROP");
8759 FIB_TEST(!fib_test_validate_entry(lfe,
8760 FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS,
8761 1,
8762 &mpls_bucket_drop),
8763 "1200/neos LB 1 buckets via: mpls-DROP");
Neale Rannsad422ed2016-11-02 14:20:04 +00008764
8765 fib_table_entry_delete(fib_index, &pfx_2_2_2_4_s_32, FIB_SOURCE_API);
8766
8767 dpo_reset(&ip_1200);
8768
8769 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008770 * An rx-interface route.
8771 * like the tail of an mcast LSP
8772 */
8773 dpo_id_t idpo = DPO_INVALID;
8774
Neale Ranns43161a82017-08-12 02:12:00 -07008775 interface_rx_dpo_add_or_lock(DPO_PROTO_IP4,
Neale Ranns2303cb12018-02-21 04:57:17 -08008776 tm->hw[0]->sw_if_index,
8777 &idpo);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008778
8779 fib_prefix_t pfx_2500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008780 .fp_len = 21,
8781 .fp_proto = FIB_PROTOCOL_MPLS,
8782 .fp_label = 2500,
8783 .fp_eos = MPLS_EOS,
8784 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008785 };
8786 fib_test_lb_bucket_t rx_intf_0 = {
8787 .type = FT_LB_INTF,
8788 .adj = {
8789 .adj = idpo.dpoi_index,
8790 },
8791 };
8792
8793 lfe = fib_table_entry_update_one_path(fib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008794 &pfx_2500,
8795 FIB_SOURCE_API,
8796 FIB_ENTRY_FLAG_NONE,
8797 DPO_PROTO_IP4,
8798 NULL,
8799 tm->hw[0]->sw_if_index,
8800 ~0, // invalid fib index
8801 0,
8802 NULL,
8803 FIB_ROUTE_PATH_INTF_RX);
8804 FIB_TEST(!fib_test_validate_entry(lfe,
8805 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8806 1,
8807 &rx_intf_0),
8808 "2500 rx-interface 0");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008809 fib_table_entry_delete(fib_index, &pfx_2500, FIB_SOURCE_API);
8810
8811 /*
8812 * An MPLS mulicast entry
8813 */
8814 fib_prefix_t pfx_3500 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008815 .fp_len = 21,
8816 .fp_proto = FIB_PROTOCOL_MPLS,
8817 .fp_label = 3500,
8818 .fp_eos = MPLS_EOS,
8819 .fp_payload_proto = DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008820 };
8821 fib_test_rep_bucket_t mc_0 = {
8822 .type = FT_REP_LABEL_O_ADJ,
Neale Ranns2303cb12018-02-21 04:57:17 -08008823 .label_o_adj = {
8824 .adj = ai_mpls_10_10_10_1,
8825 .label = 3300,
8826 .eos = MPLS_EOS,
8827 },
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008828 };
8829 fib_test_rep_bucket_t mc_intf_0 = {
8830 .type = FT_REP_INTF,
8831 .adj = {
8832 .adj = idpo.dpoi_index,
8833 },
8834 };
Neale Ranns31ed7442018-02-23 05:29:09 -08008835 fib_mpls_label_t *l3300 = NULL, fml_3300 = {
8836 .fml_value = 3300,
8837 };
8838 vec_add1(l3300, fml_3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008839
8840 lfe = fib_table_entry_update_one_path(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008841 &pfx_3500,
8842 FIB_SOURCE_API,
8843 FIB_ENTRY_FLAG_MULTICAST,
8844 DPO_PROTO_IP4,
8845 &nh_10_10_10_1,
8846 tm->hw[0]->sw_if_index,
8847 ~0, // invalid fib index
8848 1,
8849 l3300,
8850 FIB_ROUTE_PATH_FLAG_NONE);
8851 FIB_TEST(!fib_test_validate_entry(lfe,
8852 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8853 1,
8854 &mc_0),
8855 "3500 via replicate over 10.10.10.1");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008856
8857 /*
8858 * MPLS Bud-node. Add a replication via an interface-receieve path
8859 */
8860 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008861 &pfx_3500,
8862 FIB_SOURCE_API,
8863 FIB_ENTRY_FLAG_MULTICAST,
8864 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008865 NULL,
8866 tm->hw[0]->sw_if_index,
8867 ~0, // invalid fib index
8868 0,
8869 NULL,
8870 FIB_ROUTE_PATH_INTF_RX);
Neale Ranns2303cb12018-02-21 04:57:17 -08008871 FIB_TEST(!fib_test_validate_entry(lfe,
8872 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8873 2,
8874 &mc_0,
8875 &mc_intf_0),
8876 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008877
8878 /*
8879 * Add a replication via an interface-free for-us path
8880 */
8881 fib_test_rep_bucket_t mc_disp = {
8882 .type = FT_REP_DISP_MFIB_LOOKUP,
8883 .adj = {
8884 .adj = idpo.dpoi_index,
8885 },
8886 };
8887 lfe = fib_table_entry_path_add(lfib_index,
Neale Ranns2303cb12018-02-21 04:57:17 -08008888 &pfx_3500,
8889 FIB_SOURCE_API,
8890 FIB_ENTRY_FLAG_MULTICAST,
8891 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008892 NULL,
8893 5, // rpf-id
8894 0, // default table
8895 0,
8896 NULL,
8897 FIB_ROUTE_PATH_RPF_ID);
Neale Ranns2303cb12018-02-21 04:57:17 -08008898 FIB_TEST(!fib_test_validate_entry(lfe,
8899 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
8900 3,
8901 &mc_0,
8902 &mc_disp,
8903 &mc_intf_0),
8904 "3500 via replicate over 10.10.10.1 and interface-rx");
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008905
8906
Neale Ranns2303cb12018-02-21 04:57:17 -08008907
Neale Ranns0f26c5a2017-03-01 15:12:11 -08008908 fib_table_entry_delete(fib_index, &pfx_3500, FIB_SOURCE_API);
8909 dpo_reset(&idpo);
8910
8911 /*
Neale Rannsad422ed2016-11-02 14:20:04 +00008912 * cleanup
8913 */
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008914 mpls_sw_interface_enable_disable(&mpls_main,
8915 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07008916 0, 1);
8917 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008918
Neale Ranns31ed7442018-02-23 05:29:09 -08008919 FIB_TEST(0 == pool_elts(mpls_disp_dpo_pool),
8920 "mpls_disp_dpo resources freed %d of %d",
8921 0, pool_elts(mpls_disp_dpo_pool));
Neale Rannsad422ed2016-11-02 14:20:04 +00008922 FIB_TEST(lb_count == pool_elts(load_balance_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008923 "Load-balance resources freed %d of %d",
Neale Rannsad422ed2016-11-02 14:20:04 +00008924 lb_count, pool_elts(load_balance_pool));
Neale Ranns43161a82017-08-12 02:12:00 -07008925 FIB_TEST(0 == pool_elts(interface_rx_dpo_pool),
Neale Ranns2303cb12018-02-21 04:57:17 -08008926 "interface_rx_dpo resources freed %d of %d",
Neale Ranns43161a82017-08-12 02:12:00 -07008927 0, pool_elts(interface_rx_dpo_pool));
Neale Ranns0ebe8d72016-12-08 19:48:11 +00008928
Neale Ranns2303cb12018-02-21 04:57:17 -08008929 return (res);
Neale Ranns0bfe5d82016-08-25 15:29:12 +01008930}
8931
Neale Ranns89541992017-04-06 04:41:02 -07008932static int
8933fib_test_inherit (void)
8934{
8935 fib_node_index_t fei;
8936 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -08008937 int n_feis, res;
Neale Ranns89541992017-04-06 04:41:02 -07008938
Neale Ranns2303cb12018-02-21 04:57:17 -08008939 res = 0;
Neale Ranns89541992017-04-06 04:41:02 -07008940 n_feis = fib_entry_pool_size();
8941 tm = &test_main;
8942
8943 const ip46_address_t nh_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008944 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a01),
Neale Ranns89541992017-04-06 04:41:02 -07008945 };
8946 const ip46_address_t nh_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008947 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02),
8948 };
8949 const ip46_address_t nh_10_10_10_3 = {
8950 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a03),
Neale Ranns89541992017-04-06 04:41:02 -07008951 };
8952 const ip46_address_t nh_10_10_10_16 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008953 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a10),
Neale Ranns89541992017-04-06 04:41:02 -07008954 };
8955 const ip46_address_t nh_10_10_10_20 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008956 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a14),
Neale Ranns89541992017-04-06 04:41:02 -07008957 };
8958 const ip46_address_t nh_10_10_10_21 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008959 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a15),
Neale Ranns89541992017-04-06 04:41:02 -07008960 };
8961 const ip46_address_t nh_10_10_10_22 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008962 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a16),
Neale Ranns89541992017-04-06 04:41:02 -07008963 };
8964 const ip46_address_t nh_10_10_10_255 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008965 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0aff),
Neale Ranns89541992017-04-06 04:41:02 -07008966 };
8967 const ip46_address_t nh_10_10_10_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008968 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a00),
Neale Ranns89541992017-04-06 04:41:02 -07008969 };
8970 const ip46_address_t nh_10_10_0_0 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08008971 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0000),
8972 };
8973 const ip46_address_t nh_11_11_11_11 = {
8974 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b0b),
8975 };
8976 const ip46_address_t nh_11_11_11_0 = {
8977 .ip4.as_u32 = clib_host_to_net_u32(0x0b0b0b00),
Neale Ranns89541992017-04-06 04:41:02 -07008978 };
8979
8980 /*
8981 * prefixes at the base of a sub-tree
8982 */
8983 const fib_prefix_t pfx_10_10_10_21_s_32 = {
8984 .fp_len = 32,
8985 .fp_proto = FIB_PROTOCOL_IP4,
8986 .fp_addr = nh_10_10_10_21,
8987 };
8988 const fib_prefix_t pfx_10_10_10_22_s_32 = {
8989 .fp_len = 32,
8990 .fp_proto = FIB_PROTOCOL_IP4,
8991 .fp_addr = nh_10_10_10_22,
8992 };
8993 const fib_prefix_t pfx_10_10_10_255_s_32 = {
8994 .fp_len = 32,
8995 .fp_proto = FIB_PROTOCOL_IP4,
8996 .fp_addr = nh_10_10_10_255,
8997 };
Neale Ranns2303cb12018-02-21 04:57:17 -08008998 const u32 N_PLS = fib_path_list_pool_size();
Neale Ranns89541992017-04-06 04:41:02 -07008999
9000 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009001 &pfx_10_10_10_21_s_32,
9002 FIB_SOURCE_CLI,
9003 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009004 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009005 &pfx_10_10_10_22_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_255_s_32,
9010 FIB_SOURCE_CLI,
9011 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009012
9013 /*
9014 * source an entry that pushes its state down the sub-tree
9015 */
9016 const fib_prefix_t pfx_10_10_10_16_s_28 = {
9017 .fp_len = 28,
9018 .fp_proto = FIB_PROTOCOL_IP4,
9019 .fp_addr = nh_10_10_10_16,
9020 };
9021 fib_table_entry_update_one_path(0,
9022 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009023 FIB_SOURCE_API,
9024 FIB_ENTRY_FLAG_COVERED_INHERIT,
9025 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009026 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009027 tm->hw[0]->sw_if_index,
9028 ~0,
9029 1,
9030 NULL,
9031 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009032
9033 /*
9034 * this covering entry and all those below it should have
9035 * the same forwarding information.
9036 */
9037 adj_index_t ai_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9038 VNET_LINK_IP4,
9039 &nh_10_10_10_1,
9040 tm->hw[0]->sw_if_index);
9041 fib_test_lb_bucket_t adj_o_10_10_10_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009042 .type = FT_LB_ADJ,
9043 .adj = {
9044 .adj = ai_10_10_10_1,
9045 },
Neale Ranns89541992017-04-06 04:41:02 -07009046 };
9047
9048 fei = fib_table_lookup(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009049 FIB_TEST(!fib_test_validate_entry(fei,
9050 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9051 1,
9052 &adj_o_10_10_10_1),
9053 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009054 format_fib_prefix, &pfx_10_10_10_16_s_28);
9055 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009056 FIB_TEST(!fib_test_validate_entry(fei,
9057 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9058 1,
9059 &adj_o_10_10_10_1),
9060 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009061 format_fib_prefix, &pfx_10_10_10_21_s_32);
9062 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009063 FIB_TEST(!fib_test_validate_entry(fei,
9064 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9065 1,
9066 &adj_o_10_10_10_1),
9067 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009068 format_fib_prefix, &pfx_10_10_10_22_s_32);
9069 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
9070 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9071 "%U resolves via drop",
9072 format_fib_prefix, &pfx_10_10_10_255_s_32);
9073
9074 /*
9075 * remove the inherting cover - covereds go back to drop
9076 */
9077 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9078
9079 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9080 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9081 "%U resolves via drop",
9082 format_fib_prefix, &pfx_10_10_10_21_s_32);
9083
9084 /*
9085 * source an entry that pushes its state down the sub-tree
9086 */
9087 const fib_prefix_t pfx_10_10_10_0_s_24 = {
9088 .fp_len = 24,
9089 .fp_proto = FIB_PROTOCOL_IP4,
9090 .fp_addr = nh_10_10_10_0,
9091 };
9092 fib_table_entry_update_one_path(0,
9093 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009094 FIB_SOURCE_API,
9095 FIB_ENTRY_FLAG_COVERED_INHERIT,
9096 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009097 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009098 tm->hw[0]->sw_if_index,
9099 ~0,
9100 1,
9101 NULL,
9102 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009103
9104 /*
9105 * whole sub-tree now covered
9106 */
9107 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009108 FIB_TEST(!fib_test_validate_entry(fei,
9109 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9110 1,
9111 &adj_o_10_10_10_1),
9112 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009113 format_fib_prefix, &pfx_10_10_10_0_s_24);
9114 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009115 FIB_TEST(!fib_test_validate_entry(fei,
9116 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9117 1,
9118 &adj_o_10_10_10_1),
9119 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009120 format_fib_prefix, &pfx_10_10_10_21_s_32);
9121 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009122 FIB_TEST(!fib_test_validate_entry(fei,
9123 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9124 1,
9125 &adj_o_10_10_10_1),
9126 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009127 format_fib_prefix, &pfx_10_10_10_22_s_32);
9128 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009129 FIB_TEST(!fib_test_validate_entry(fei,
9130 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9131 1,
9132 &adj_o_10_10_10_1),
9133 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009134 format_fib_prefix, &pfx_10_10_10_255_s_32);
9135
9136 /*
9137 * insert a more specific into the sub-tree - expect inheritance
9138 * this one is directly covered by the root
9139 */
9140 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009141 &pfx_10_10_10_16_s_28,
9142 FIB_SOURCE_CLI,
9143 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009144 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009145 FIB_TEST(!fib_test_validate_entry(fei,
9146 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9147 1,
9148 &adj_o_10_10_10_1),
9149 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009150 format_fib_prefix, &pfx_10_10_10_16_s_28);
9151
9152 /*
9153 * insert a more specific into the sub-tree - expect inheritance
9154 * this one is indirectly covered by the root
9155 */
9156 const fib_prefix_t pfx_10_10_10_20_s_30 = {
9157 .fp_len = 30,
9158 .fp_proto = FIB_PROTOCOL_IP4,
9159 .fp_addr = nh_10_10_10_20,
9160 };
9161 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -08009162 &pfx_10_10_10_20_s_30,
9163 FIB_SOURCE_CLI,
9164 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -07009165 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
Neale Ranns2303cb12018-02-21 04:57:17 -08009166 FIB_TEST(!fib_test_validate_entry(fei,
9167 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9168 1,
9169 &adj_o_10_10_10_1),
9170 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009171 format_fib_prefix, &pfx_10_10_10_20_s_30);
9172
9173 /*
9174 * remove the prefix from the middle of the sub-tree
9175 * the inherited source will be the only one remaining - expect
9176 * it to be withdrawn and hence the prefix is removed.
9177 */
9178 fib_table_entry_special_remove(0,
9179 &pfx_10_10_10_20_s_30,
9180 FIB_SOURCE_CLI);
9181 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_20_s_30);
9182 FIB_TEST((FIB_NODE_INDEX_INVALID == fei),
9183 "%U gone",
9184 format_fib_prefix, &pfx_10_10_10_20_s_30);
9185
9186 /*
9187 * inheriting source is modifed - expect the modification to be present
9188 * throughout the sub-tree
9189 */
9190 adj_index_t ai_10_10_10_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9191 VNET_LINK_IP4,
9192 &nh_10_10_10_2,
9193 tm->hw[0]->sw_if_index);
9194 fib_test_lb_bucket_t adj_o_10_10_10_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009195 .type = FT_LB_ADJ,
9196 .adj = {
9197 .adj = ai_10_10_10_2,
9198 },
Neale Ranns89541992017-04-06 04:41:02 -07009199 };
9200
9201 fib_table_entry_update_one_path(0,
9202 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009203 FIB_SOURCE_API,
9204 FIB_ENTRY_FLAG_COVERED_INHERIT,
9205 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009206 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009207 tm->hw[0]->sw_if_index,
9208 ~0,
9209 1,
9210 NULL,
9211 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009212 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009213 FIB_TEST(!fib_test_validate_entry(fei,
9214 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9215 1,
9216 &adj_o_10_10_10_2),
9217 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009218 format_fib_prefix, &pfx_10_10_10_21_s_32);
9219 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009220 FIB_TEST(!fib_test_validate_entry(fei,
9221 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9222 1,
9223 &adj_o_10_10_10_2),
9224 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009225 format_fib_prefix, &pfx_10_10_10_22_s_32);
9226 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009227 FIB_TEST(!fib_test_validate_entry(fei,
9228 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9229 1,
9230 &adj_o_10_10_10_2),
9231 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009232 format_fib_prefix, &pfx_10_10_10_255_s_32);
9233 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009234 FIB_TEST(!fib_test_validate_entry(fei,
9235 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9236 1,
9237 &adj_o_10_10_10_2),
9238 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009239 format_fib_prefix, &pfx_10_10_10_0_s_24);
9240
9241 /*
9242 * add the source that replaces inherited state.
9243 * inheriting source is not the best, so it doesn't push state.
9244 */
9245 fib_table_entry_update_one_path(0,
9246 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009247 FIB_SOURCE_PLUGIN_HI,
9248 FIB_ENTRY_FLAG_NONE,
9249 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009250 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009251 tm->hw[0]->sw_if_index,
9252 ~0,
9253 1,
9254 NULL,
9255 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009256 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009257 FIB_TEST(!fib_test_validate_entry(fei,
9258 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9259 1,
9260 &adj_o_10_10_10_1),
9261 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009262 format_fib_prefix, &pfx_10_10_10_0_s_24);
9263
9264 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9265 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
9266 "%U resolves via drop",
9267 format_fib_prefix, &pfx_10_10_10_21_s_32);
9268 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_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_22_s_32);
9272 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_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_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009276 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009277 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_16_s_28);
9280
9281 /*
9282 * withdraw the higher priority source and expect the inherited to return
9283 * throughout the sub-tree
9284 */
9285 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_PLUGIN_HI);
9286
9287 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009288 FIB_TEST(!fib_test_validate_entry(fei,
9289 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9290 1,
9291 &adj_o_10_10_10_2),
9292 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009293 format_fib_prefix, &pfx_10_10_10_21_s_32);
9294 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009295 FIB_TEST(!fib_test_validate_entry(fei,
9296 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9297 1,
9298 &adj_o_10_10_10_2),
9299 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009300 format_fib_prefix, &pfx_10_10_10_22_s_32);
9301 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009302 FIB_TEST(!fib_test_validate_entry(fei,
9303 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9304 1,
9305 &adj_o_10_10_10_2),
9306 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009307 format_fib_prefix, &pfx_10_10_10_255_s_32);
9308 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009309 FIB_TEST(!fib_test_validate_entry(fei,
9310 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9311 1,
9312 &adj_o_10_10_10_2),
9313 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009314 format_fib_prefix, &pfx_10_10_10_0_s_24);
9315 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009316 FIB_TEST(!fib_test_validate_entry(fei,
9317 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9318 1,
9319 &adj_o_10_10_10_2),
9320 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009321 format_fib_prefix, &pfx_10_10_10_16_s_28);
9322
9323 /*
9324 * source a covered entry in the sub-tree with the same inherting source
9325 * - expect that it now owns the sub-tree and thus over-rides its cover
9326 */
9327 fib_table_entry_update_one_path(0,
9328 &pfx_10_10_10_16_s_28,
Neale Ranns2303cb12018-02-21 04:57:17 -08009329 FIB_SOURCE_API,
9330 FIB_ENTRY_FLAG_COVERED_INHERIT,
9331 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009332 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009333 tm->hw[0]->sw_if_index,
9334 ~0,
9335 1,
9336 NULL,
9337 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009338 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009339 FIB_TEST(!fib_test_validate_entry(fei,
9340 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9341 1,
9342 &adj_o_10_10_10_1),
9343 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009344 format_fib_prefix, &pfx_10_10_10_16_s_28);
9345 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009346 FIB_TEST(!fib_test_validate_entry(fei,
9347 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9348 1,
9349 &adj_o_10_10_10_1),
9350 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009351 format_fib_prefix, &pfx_10_10_10_22_s_32);
9352 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009353 FIB_TEST(!fib_test_validate_entry(fei,
9354 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9355 1,
9356 &adj_o_10_10_10_1),
9357 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009358 format_fib_prefix, &pfx_10_10_10_21_s_32);
9359
9360 /* these two unaffected by the sub-tree change */
9361 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009362 FIB_TEST(!fib_test_validate_entry(fei,
9363 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9364 1,
9365 &adj_o_10_10_10_2),
9366 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009367 format_fib_prefix, &pfx_10_10_10_255_s_32);
9368 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009369 FIB_TEST(!fib_test_validate_entry(fei,
9370 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9371 1,
9372 &adj_o_10_10_10_2),
9373 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009374 format_fib_prefix, &pfx_10_10_10_0_s_24);
9375
9376 /*
9377 * removes the more specific, expect the /24 to now re-owns the sub-tree
9378 */
9379 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_API);
9380
9381 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009382 FIB_TEST(!fib_test_validate_entry(fei,
9383 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9384 1,
9385 &adj_o_10_10_10_2),
9386 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009387 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009388 FIB_TEST(!fib_test_validate_entry(fei,
9389 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9390 1,
9391 &adj_o_10_10_10_2),
9392 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009393 format_fib_prefix, &pfx_10_10_10_21_s_32);
9394 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009395 FIB_TEST(!fib_test_validate_entry(fei,
9396 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9397 1,
9398 &adj_o_10_10_10_2),
9399 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009400 format_fib_prefix, &pfx_10_10_10_22_s_32);
9401 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009402 FIB_TEST(!fib_test_validate_entry(fei,
9403 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9404 1,
9405 &adj_o_10_10_10_2),
9406 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009407 format_fib_prefix, &pfx_10_10_10_255_s_32);
9408 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009409 FIB_TEST(!fib_test_validate_entry(fei,
9410 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9411 1,
9412 &adj_o_10_10_10_2),
9413 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009414 format_fib_prefix, &pfx_10_10_10_0_s_24);
9415 /*
9416 * modify the /24. expect the new forwarding to be pushed down
9417 */
9418 fib_table_entry_update_one_path(0,
9419 &pfx_10_10_10_0_s_24,
Neale Ranns2303cb12018-02-21 04:57:17 -08009420 FIB_SOURCE_API,
9421 FIB_ENTRY_FLAG_COVERED_INHERIT,
9422 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009423 &nh_10_10_10_1,
Neale Ranns2303cb12018-02-21 04:57:17 -08009424 tm->hw[0]->sw_if_index,
9425 ~0,
9426 1,
9427 NULL,
9428 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009429 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009430 FIB_TEST(!fib_test_validate_entry(fei,
9431 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9432 1,
9433 &adj_o_10_10_10_1),
9434 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009435 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns2303cb12018-02-21 04:57:17 -08009436 FIB_TEST(!fib_test_validate_entry(fei,
9437 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9438 1,
9439 &adj_o_10_10_10_1),
9440 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009441 format_fib_prefix, &pfx_10_10_10_21_s_32);
9442 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009443 FIB_TEST(!fib_test_validate_entry(fei,
9444 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9445 1,
9446 &adj_o_10_10_10_1),
9447 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009448 format_fib_prefix, &pfx_10_10_10_22_s_32);
9449 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009450 FIB_TEST(!fib_test_validate_entry(fei,
9451 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9452 1,
9453 &adj_o_10_10_10_1),
9454 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009455 format_fib_prefix, &pfx_10_10_10_255_s_32);
9456 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009457 FIB_TEST(!fib_test_validate_entry(fei,
9458 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9459 1,
9460 &adj_o_10_10_10_1),
9461 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009462 format_fib_prefix, &pfx_10_10_10_0_s_24);
9463
9464 /*
9465 * add an entry less specific to /24. it should not own the /24's tree
9466 */
9467 const fib_prefix_t pfx_10_10_0_0_s_16 = {
9468 .fp_len = 16,
9469 .fp_proto = FIB_PROTOCOL_IP4,
9470 .fp_addr = nh_10_10_0_0,
9471 };
9472 fib_table_entry_update_one_path(0,
9473 &pfx_10_10_0_0_s_16,
Neale Ranns2303cb12018-02-21 04:57:17 -08009474 FIB_SOURCE_API,
9475 FIB_ENTRY_FLAG_COVERED_INHERIT,
9476 DPO_PROTO_IP4,
Neale Ranns89541992017-04-06 04:41:02 -07009477 &nh_10_10_10_2,
Neale Ranns2303cb12018-02-21 04:57:17 -08009478 tm->hw[0]->sw_if_index,
9479 ~0,
9480 1,
9481 NULL,
9482 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -07009483 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009484 FIB_TEST(!fib_test_validate_entry(fei,
9485 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9486 1,
9487 &adj_o_10_10_10_1),
9488 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009489 format_fib_prefix, &pfx_10_10_10_16_s_28);
Neale Ranns89541992017-04-06 04:41:02 -07009490 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_22_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009491 FIB_TEST(!fib_test_validate_entry(fei,
9492 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9493 1,
9494 &adj_o_10_10_10_1),
9495 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009496 format_fib_prefix, &pfx_10_10_10_22_s_32);
9497 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_255_s_32);
Neale Ranns2303cb12018-02-21 04:57:17 -08009498 FIB_TEST(!fib_test_validate_entry(fei,
9499 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9500 1,
9501 &adj_o_10_10_10_1),
9502 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009503 format_fib_prefix, &pfx_10_10_10_255_s_32);
9504 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
Neale Ranns2303cb12018-02-21 04:57:17 -08009505 FIB_TEST(!fib_test_validate_entry(fei,
9506 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9507 1,
9508 &adj_o_10_10_10_1),
9509 "%U via 10.10.10.1",
Neale Ranns89541992017-04-06 04:41:02 -07009510 format_fib_prefix, &pfx_10_10_10_0_s_24);
9511 fei = fib_table_lookup_exact_match(0, &pfx_10_10_0_0_s_16);
Neale Ranns2303cb12018-02-21 04:57:17 -08009512 FIB_TEST(!fib_test_validate_entry(fei,
9513 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9514 1,
9515 &adj_o_10_10_10_2),
9516 "%U via 10.10.10.2",
Neale Ranns89541992017-04-06 04:41:02 -07009517 format_fib_prefix, &pfx_10_10_0_0_s_16);
9518
9519 /*
Neale Ranns2303cb12018-02-21 04:57:17 -08009520 * Add/remove an interposer source to a new /32
9521 */
9522 const fib_prefix_t pfx_11_11_11_11_s_32 = {
9523 .fp_len = 32,
9524 .fp_proto = FIB_PROTOCOL_IP4,
9525 .fp_addr = nh_11_11_11_11,
9526 };
9527
9528 fib_table_entry_update_one_path(0,
9529 &pfx_11_11_11_11_s_32,
9530 FIB_SOURCE_API,
9531 FIB_ENTRY_FLAG_NONE,
9532 DPO_PROTO_IP4,
9533 &nh_10_10_10_3,
9534 tm->hw[0]->sw_if_index,
9535 ~0,
9536 1,
9537 NULL,
9538 FIB_ROUTE_PATH_FLAG_NONE);
9539
9540 dpo_id_t interposer = DPO_INVALID;
9541 fib_mpls_label_t *l99 = NULL, fml_99 = {
9542 .fml_value = 99,
9543 };
9544 vec_add1(l99, fml_99);
9545
9546 mpls_label_dpo_create(l99,
9547 MPLS_EOS,
9548 DPO_PROTO_IP4,
9549 MPLS_LABEL_DPO_FLAG_NONE,
9550 punt_dpo_get(DPO_PROTO_MPLS),
9551 &interposer);
9552
9553 adj_index_t ai_10_10_10_3 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
9554 VNET_LINK_IP4,
9555 &nh_10_10_10_3,
9556 tm->hw[0]->sw_if_index);
9557 fib_test_lb_bucket_t adj_o_10_10_10_3 = {
9558 .type = FT_LB_ADJ,
9559 .adj = {
9560 .adj = ai_10_10_10_3,
9561 },
9562 };
9563 fib_test_lb_bucket_t l99_o_10_10_10_3 = {
9564 .type = FT_LB_LABEL_O_ADJ,
9565 .label_o_adj = {
9566 .adj = ai_10_10_10_3,
9567 .label = 99,
9568 .eos = MPLS_EOS,
9569 },
9570 };
9571
9572 fei = fib_table_entry_special_dpo_add(0,
9573 &pfx_11_11_11_11_s_32,
9574 FIB_SOURCE_SPECIAL,
9575 FIB_ENTRY_FLAG_INTERPOSE,
9576 &interposer);
9577 FIB_TEST(!fib_test_validate_entry(fei,
9578 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9579 1,
9580 &l99_o_10_10_10_3),
9581 "%U via interposer adj",
9582 format_fib_prefix,&pfx_11_11_11_11_s_32);
9583
9584 fib_table_entry_special_remove(0,
9585 &pfx_11_11_11_11_s_32,
9586 FIB_SOURCE_SPECIAL);
9587 FIB_TEST(!fib_test_validate_entry(fei,
9588 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9589 1,
9590 &adj_o_10_10_10_3),
9591 "%U via 10.10.10.1",
9592 format_fib_prefix, &pfx_11_11_11_11_s_32);
9593
9594 /*
9595 * remove and re-add the second best API source while the interpose
9596 * is present
9597 */
9598 fei = fib_table_entry_special_dpo_add(0,
9599 &pfx_11_11_11_11_s_32,
9600 FIB_SOURCE_SPECIAL,
9601 FIB_ENTRY_FLAG_INTERPOSE,
9602 &interposer);
9603 FIB_TEST(!fib_test_validate_entry(fei,
9604 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9605 1,
9606 &l99_o_10_10_10_3),
9607 "%U via interposer adj",
9608 format_fib_prefix,&pfx_11_11_11_11_s_32);
9609
9610 FIB_TEST(2 == pool_elts(mpls_label_dpo_pool),
9611 "MPLS label pool: %d",
9612 pool_elts(mpls_label_dpo_pool));
9613
9614 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9615
9616 /*
9617 * the interpose does not get stacked when there are not valid paths
9618 */
9619 fib_test_lb_bucket_t bucket_drop = {
9620 .type = FT_LB_DROP,
9621 .special = {
9622 .adj = DPO_PROTO_IP4,
9623 },
9624 };
9625 FIB_TEST(!fib_test_validate_entry(fei,
9626 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9627 1,
9628 &bucket_drop),
9629 "%U via drop",
9630 format_fib_prefix,&pfx_11_11_11_11_s_32);
9631
9632 fib_table_entry_update_one_path(0,
9633 &pfx_11_11_11_11_s_32,
9634 FIB_SOURCE_API,
9635 FIB_ENTRY_FLAG_NONE,
9636 DPO_PROTO_IP4,
9637 &nh_10_10_10_3,
9638 tm->hw[0]->sw_if_index,
9639 ~0,
9640 1,
9641 NULL,
9642 FIB_ROUTE_PATH_FLAG_NONE);
9643 FIB_TEST(!fib_test_validate_entry(fei,
9644 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9645 1,
9646 &l99_o_10_10_10_3),
9647 "%U via interposer adj",
9648 format_fib_prefix,&pfx_11_11_11_11_s_32);
9649 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API);
9650
9651 /*
9652 * add a cover for the interposed entry, so that we test it selects
9653 * the covers forwarding.
9654 */
9655 const fib_prefix_t pfx_11_11_11_0_s_24 = {
9656 .fp_len = 24,
9657 .fp_proto = FIB_PROTOCOL_IP4,
9658 .fp_addr = nh_11_11_11_0,
9659 };
9660 fib_table_entry_update_one_path(0,
9661 &pfx_11_11_11_0_s_24,
9662 FIB_SOURCE_API,
9663 FIB_ENTRY_FLAG_NONE,
9664 DPO_PROTO_IP4,
9665 &nh_10_10_10_3,
9666 tm->hw[0]->sw_if_index,
9667 ~0,
9668 1,
9669 NULL,
9670 FIB_ROUTE_PATH_FLAG_NONE);
9671 FIB_TEST(!fib_test_validate_entry(fei,
9672 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9673 1,
9674 &l99_o_10_10_10_3),
9675 "%U via interposer adj",
9676 format_fib_prefix,&pfx_11_11_11_11_s_32);
9677
9678 /*
9679 * multiple interpose sources on the same entry. Only the high
9680 * priority source gets to add the interpose.
9681 */
9682 dpo_id_t interposer2 = DPO_INVALID;
9683 fib_mpls_label_t *l100 = NULL, fml_100 = {
9684 .fml_value = 100,
9685 };
9686 vec_add1(l100, fml_100);
9687
9688 mpls_label_dpo_create(l100,
9689 MPLS_EOS,
9690 DPO_PROTO_IP4,
9691 MPLS_LABEL_DPO_FLAG_NONE,
9692 punt_dpo_get(DPO_PROTO_MPLS),
9693 &interposer2);
9694
9695 fei = fib_table_entry_special_dpo_add(0,
9696 &pfx_11_11_11_11_s_32,
9697 FIB_SOURCE_CLASSIFY,
9698 FIB_ENTRY_FLAG_INTERPOSE,
9699 &interposer2);
9700 FIB_TEST(!fib_test_validate_entry(fei,
9701 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9702 1,
9703 &l99_o_10_10_10_3),
9704 "%U via interposer label 99",
9705 format_fib_prefix,&pfx_11_11_11_11_s_32);
9706
9707 fib_test_lb_bucket_t l100_o_10_10_10_3 = {
9708 .type = FT_LB_LABEL_O_ADJ,
9709 .label_o_adj = {
9710 .adj = ai_10_10_10_3,
9711 .label = 100,
9712 .eos = MPLS_EOS,
9713 },
9714 };
9715
9716 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_SPECIAL);
9717
9718 FIB_TEST(!fib_test_validate_entry(fei,
9719 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9720 1,
9721 &l100_o_10_10_10_3),
9722 "%U via interposer label 99",
9723 format_fib_prefix,&pfx_11_11_11_11_s_32);
9724
9725 fib_table_entry_delete(0, &pfx_11_11_11_0_s_24, FIB_SOURCE_API);
9726 FIB_TEST(!fib_test_validate_entry(fei,
9727 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9728 1,
9729 &bucket_drop),
9730 "%U via drop",
9731 format_fib_prefix,&pfx_11_11_11_11_s_32);
9732 fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_CLASSIFY);
9733
9734 /*
9735 * update a source to/from interpose.
9736 */
9737 /* fib_table_entry_update_one_path(0, */
9738 /* &pfx_11_11_11_0_s_24, */
9739 /* FIB_SOURCE_API, */
9740 /* FIB_ENTRY_FLAG_NONE, */
9741 /* DPO_PROTO_IP4, */
9742 /* &nh_10_10_10_3, */
9743 /* tm->hw[0]->sw_if_index, */
9744 /* ~0, */
9745 /* 1, */
9746 /* NULL, */
9747 /* FIB_ROUTE_PATH_FLAG_NONE); */
9748 /* fei = fib_table_entry_special_dpo_add(0, */
9749 /* &pfx_11_11_11_11_s_32, */
9750 /* FIB_SOURCE_API, */
9751 /* FIB_ENTRY_FLAG_INTERPOSE, */
9752 /* &interposer); */
9753 /* FIB_TEST(!fib_test_validate_entry(fei, */
9754 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9755 /* 1, */
9756 /* &l99_o_10_10_10_3), */
9757 /* "%U via interposer label 99", */
9758 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9759
9760 /* FIB_TEST(3 == pool_elts(mpls_label_dpo_pool), */
9761 /* "MPLS label pool: %d", */
9762 /* pool_elts(mpls_label_dpo_pool)); */
9763 /* FIB_TEST((2 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9764 /* "Interposer %d locks", */
9765 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9766
9767 /* fib_table_entry_update_one_path(0, */
9768 /* &pfx_11_11_11_11_s_32, */
9769 /* FIB_SOURCE_API, */
9770 /* FIB_ENTRY_FLAG_NONE, */
9771 /* DPO_PROTO_IP4, */
9772 /* &nh_10_10_10_2, */
9773 /* tm->hw[0]->sw_if_index, */
9774 /* ~0, */
9775 /* 1, */
9776 /* NULL, */
9777 /* FIB_ROUTE_PATH_FLAG_NONE); */
9778 /* FIB_TEST(!fib_test_validate_entry(fei, */
9779 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9780 /* 1, */
9781 /* &adj_o_10_10_10_2), */
9782 /* "%U via 10.10.10.2", */
9783 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9784
9785 /* FIB_TEST((1 == mpls_label_dpo_get(interposer.dpoi_index)->mld_locks), */
9786 /* "Interposer %d locks", */
9787 /* mpls_label_dpo_get(interposer.dpoi_index)->mld_locks); */
9788 /* FIB_TEST(2 == pool_elts(mpls_label_dpo_pool), */
9789 /* "MPLS label pool: %d", */
9790 /* pool_elts(mpls_label_dpo_pool)); */
9791
9792 /* fei = fib_table_entry_special_dpo_add(0, */
9793 /* &pfx_11_11_11_11_s_32, */
9794 /* FIB_SOURCE_API, */
9795 /* FIB_ENTRY_FLAG_INTERPOSE, */
9796 /* &interposer); */
9797 /* FIB_TEST(!fib_test_validate_entry(fei, */
9798 /* FIB_FORW_CHAIN_TYPE_UNICAST_IP4, */
9799 /* 1, */
9800 /* &l99_o_10_10_10_3), */
9801 /* "%U via interposer label 99", */
9802 /* format_fib_prefix,&pfx_11_11_11_11_s_32); */
9803
9804 /* fib_table_entry_delete(0, &pfx_11_11_11_11_s_32, FIB_SOURCE_API); */
9805
9806 /*
9807 * Add/remove an interposer source from the top of the subtrie. The
9808 * interposer source is not inherited.
9809 */
9810 fib_table_entry_update_one_path(0,
9811 &pfx_10_10_10_0_s_24,
9812 FIB_SOURCE_API,
9813 FIB_ENTRY_FLAG_COVERED_INHERIT,
9814 DPO_PROTO_IP4,
9815 &nh_10_10_10_3,
9816 tm->hw[0]->sw_if_index,
9817 ~0,
9818 1,
9819 NULL,
9820 FIB_ROUTE_PATH_FLAG_NONE);
9821 fei = fib_table_entry_special_dpo_add(0,
9822 &pfx_10_10_10_0_s_24,
9823 FIB_SOURCE_SPECIAL,
9824 FIB_ENTRY_FLAG_INTERPOSE,
9825 &interposer);
9826 FIB_TEST(!fib_test_validate_entry(fei,
9827 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9828 1,
9829 &l99_o_10_10_10_3),
9830 "%U via interposer label",
9831 format_fib_prefix,&pfx_10_10_10_0_s_24);
9832 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9833 FIB_TEST(!fib_test_validate_entry(fei,
9834 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9835 1,
9836 &bucket_drop),
9837 "%U via drop",
9838 format_fib_prefix, &pfx_10_10_10_21_s_32);
9839
9840 fib_table_entry_special_remove(0,
9841 &pfx_10_10_10_0_s_24,
9842 FIB_SOURCE_SPECIAL);
9843 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_0_s_24);
9844 FIB_TEST(!fib_test_validate_entry(fei,
9845 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9846 1,
9847 &adj_o_10_10_10_3),
9848 "%U via 10.10.10.1",
9849 format_fib_prefix, &pfx_10_10_10_0_s_24);
9850 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9851 FIB_TEST(!fib_test_validate_entry(fei,
9852 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9853 1,
9854 &adj_o_10_10_10_3),
9855 "%U via via 10.10.10.1",
9856 format_fib_prefix, &pfx_10_10_10_21_s_32);
9857
9858 /*
9859 * Add/remove an interposer source from the top of the subtrie. The
9860 * interposer source is inherited.
9861 */
9862 fei = fib_table_entry_special_dpo_add(0,
9863 &pfx_10_10_10_0_s_24,
9864 FIB_SOURCE_SPECIAL,
9865 (FIB_ENTRY_FLAG_COVERED_INHERIT |
9866 FIB_ENTRY_FLAG_INTERPOSE),
9867 &interposer);
9868 FIB_TEST(!fib_test_validate_entry(fei,
9869 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9870 1,
9871 &l99_o_10_10_10_3),
9872 "%U via interposer label",
9873 format_fib_prefix,&pfx_10_10_10_0_s_24);
9874
9875 /* interposer gets forwarding from the drop cli source */
9876 fei = fib_table_lookup_exact_match(0, &pfx_10_10_10_21_s_32);
9877 FIB_TEST(!fib_test_validate_entry(fei,
9878 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9879 1,
9880 &bucket_drop),
9881 "%U via drop",
9882 format_fib_prefix,&pfx_10_10_10_21_s_32);
9883
9884 fib_table_entry_update_one_path(0,
9885 &pfx_10_10_10_21_s_32,
9886 FIB_SOURCE_API,
9887 FIB_ENTRY_FLAG_NONE,
9888 DPO_PROTO_IP4,
9889 &nh_10_10_10_3,
9890 tm->hw[0]->sw_if_index,
9891 ~0,
9892 1,
9893 NULL,
9894 FIB_ROUTE_PATH_FLAG_NONE);
9895 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_CLI);
9896 /* interposer gets forwarding from the API source */
9897 FIB_TEST(!fib_test_validate_entry(fei,
9898 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
9899 1,
9900 &l99_o_10_10_10_3),
9901 "%U via interposer label",
9902 format_fib_prefix,&pfx_10_10_10_21_s_32);
9903
9904 /*
Neale Ranns89541992017-04-06 04:41:02 -07009905 * cleanup
9906 */
Neale Ranns89541992017-04-06 04:41:02 -07009907 fib_table_entry_delete(0, &pfx_10_10_10_22_s_32, FIB_SOURCE_CLI);
Neale Ranns2303cb12018-02-21 04:57:17 -08009908 fib_table_entry_delete(0, &pfx_10_10_10_21_s_32, FIB_SOURCE_API);
Neale Ranns89541992017-04-06 04:41:02 -07009909 fib_table_entry_delete(0, &pfx_10_10_10_16_s_28, FIB_SOURCE_CLI);
9910 fib_table_entry_delete(0, &pfx_10_10_10_255_s_32, FIB_SOURCE_CLI);
9911 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_API);
9912 fib_table_entry_delete(0, &pfx_10_10_0_0_s_16, FIB_SOURCE_API);
Neale Ranns2303cb12018-02-21 04:57:17 -08009913 fib_table_entry_delete(0, &pfx_10_10_10_0_s_24, FIB_SOURCE_SPECIAL);
Neale Ranns89541992017-04-06 04:41:02 -07009914 adj_unlock(ai_10_10_10_1);
9915 adj_unlock(ai_10_10_10_2);
Neale Ranns2303cb12018-02-21 04:57:17 -08009916 adj_unlock(ai_10_10_10_3);
9917 dpo_reset(&interposer);
9918 dpo_reset(&interposer2);
9919 FIB_TEST(0 == pool_elts(mpls_label_dpo_pool),
9920 "MPLS label pool empty: %d",
9921 pool_elts(mpls_label_dpo_pool));
9922 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
9923 FIB_TEST(N_PLS == fib_path_list_pool_size(),
9924 "number of path-lists: %d = %d",
9925 N_PLS, fib_path_list_pool_size());
Neale Ranns89541992017-04-06 04:41:02 -07009926
9927 /*
9928 * test the v6 tree walk.
Neale Ranns2303cb12018-02-21 04:57:17 -08009929 * a /64 that covers everything. a /96 that covers one /128
Neale Ranns89541992017-04-06 04:41:02 -07009930 * a second /128 covered only by the /64.
9931 */
9932 const fib_prefix_t pfx_2001_s_64 = {
9933 .fp_len = 64,
9934 .fp_proto = FIB_PROTOCOL_IP6,
9935 .fp_addr = {
9936 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009937 .as_u64 = {
9938 [0] = clib_host_to_net_u64(0x2001000000000000),
9939 [1] = clib_host_to_net_u64(0x0000000000000000),
9940 },
Neale Ranns89541992017-04-06 04:41:02 -07009941 },
9942 },
9943 };
9944 const fib_prefix_t pfx_2001_1_s_96 = {
9945 .fp_len = 96,
9946 .fp_proto = FIB_PROTOCOL_IP6,
9947 .fp_addr = {
9948 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009949 .as_u64 = {
9950 [0] = clib_host_to_net_u64(0x2001000000000000),
9951 [1] = clib_host_to_net_u64(0x1000000000000000),
9952 },
Neale Ranns89541992017-04-06 04:41:02 -07009953 },
9954 },
9955 };
9956 const fib_prefix_t pfx_2001_1_1_s_128 = {
9957 .fp_len = 128,
9958 .fp_proto = FIB_PROTOCOL_IP6,
9959 .fp_addr = {
9960 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009961 .as_u64 = {
9962 [0] = clib_host_to_net_u64(0x2001000000000000),
9963 [1] = clib_host_to_net_u64(0x1000000000000001),
9964 },
Neale Ranns89541992017-04-06 04:41:02 -07009965 },
9966 },
9967 };
9968 const fib_prefix_t pfx_2001_0_1_s_128 = {
9969 .fp_len = 128,
9970 .fp_proto = FIB_PROTOCOL_IP6,
9971 .fp_addr = {
9972 .ip6 = {
Neale Ranns2303cb12018-02-21 04:57:17 -08009973 .as_u64 = {
9974 [0] = clib_host_to_net_u64(0x2001000000000000),
9975 [1] = clib_host_to_net_u64(0x0000000000000001),
9976 },
Neale Ranns89541992017-04-06 04:41:02 -07009977 },
9978 },
9979 };
9980 const ip46_address_t nh_3000_1 = {
9981 .ip6 = {
9982 .as_u64 = {
9983 [0] = clib_host_to_net_u64(0x3000000000000000),
9984 [1] = clib_host_to_net_u64(0x0000000000000001),
9985 },
9986 },
9987 };
9988 const ip46_address_t nh_3000_2 = {
9989 .ip6 = {
9990 .as_u64 = {
9991 [0] = clib_host_to_net_u64(0x3000000000000000),
9992 [1] = clib_host_to_net_u64(0x0000000000000002),
9993 },
9994 },
9995 };
9996 adj_index_t ai_3000_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
9997 VNET_LINK_IP6,
9998 &nh_3000_1,
9999 tm->hw[0]->sw_if_index);
10000 adj_index_t ai_3000_2 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP6,
10001 VNET_LINK_IP6,
10002 &nh_3000_2,
10003 tm->hw[0]->sw_if_index);
10004 fib_test_lb_bucket_t adj_o_3000_1 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010005 .type = FT_LB_ADJ,
10006 .adj = {
10007 .adj = ai_3000_1,
10008 },
Neale Ranns89541992017-04-06 04:41:02 -070010009 };
10010 fib_test_lb_bucket_t adj_o_3000_2 = {
Neale Ranns2303cb12018-02-21 04:57:17 -080010011 .type = FT_LB_ADJ,
10012 .adj = {
10013 .adj = ai_3000_2,
10014 },
Neale Ranns89541992017-04-06 04:41:02 -070010015 };
10016
10017 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010018 &pfx_2001_0_1_s_128,
10019 FIB_SOURCE_CLI,
10020 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010021 fib_table_entry_special_add(0,
Neale Ranns2303cb12018-02-21 04:57:17 -080010022 &pfx_2001_1_1_s_128,
10023 FIB_SOURCE_CLI,
10024 FIB_ENTRY_FLAG_DROP);
Neale Ranns89541992017-04-06 04:41:02 -070010025
10026 /*
10027 * /96 has inherited forwarding pushed down to its covered /128
10028 */
10029 fib_table_entry_update_one_path(0,
10030 &pfx_2001_1_s_96,
Neale Ranns2303cb12018-02-21 04:57:17 -080010031 FIB_SOURCE_API,
10032 FIB_ENTRY_FLAG_COVERED_INHERIT,
10033 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010034 &nh_3000_1,
Neale Ranns2303cb12018-02-21 04:57:17 -080010035 tm->hw[0]->sw_if_index,
10036 ~0,
10037 1,
10038 NULL,
10039 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010040 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
Neale Ranns2303cb12018-02-21 04:57:17 -080010041 FIB_TEST(!fib_test_validate_entry(fei,
10042 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10043 1,
10044 &adj_o_3000_1),
10045 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010046 format_fib_prefix, &pfx_2001_1_s_96);
10047 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010048 FIB_TEST(!fib_test_validate_entry(fei,
10049 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10050 1,
10051 &adj_o_3000_1),
10052 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010053 format_fib_prefix, &pfx_2001_1_1_s_128);
10054 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
10055 FIB_TEST(load_balance_is_drop(fib_entry_contribute_ip_forwarding(fei)),
10056 "%U resolves via drop",
10057 format_fib_prefix, &pfx_2001_0_1_s_128);
10058
10059 /*
10060 * /64 has inherited forwarding pushed down to all, but the /96
10061 * and its sub-tree remain unaffected.
10062 */
10063 fib_table_entry_update_one_path(0,
10064 &pfx_2001_s_64,
Neale Ranns2303cb12018-02-21 04:57:17 -080010065 FIB_SOURCE_API,
10066 FIB_ENTRY_FLAG_COVERED_INHERIT,
10067 DPO_PROTO_IP6,
Neale Ranns89541992017-04-06 04:41:02 -070010068 &nh_3000_2,
Neale Ranns2303cb12018-02-21 04:57:17 -080010069 tm->hw[0]->sw_if_index,
10070 ~0,
10071 1,
10072 NULL,
10073 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns89541992017-04-06 04:41:02 -070010074
10075 fei = fib_table_lookup_exact_match(0, &pfx_2001_s_64);
Neale Ranns2303cb12018-02-21 04:57:17 -080010076 FIB_TEST(!fib_test_validate_entry(fei,
10077 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10078 1,
10079 &adj_o_3000_2),
10080 "%U via 3000::2",
Neale Ranns89541992017-04-06 04:41:02 -070010081 format_fib_prefix, &pfx_2001_s_64);
10082 fei = fib_table_lookup_exact_match(0, &pfx_2001_0_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010083 FIB_TEST(!fib_test_validate_entry(fei,
10084 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10085 1,
10086 &adj_o_3000_2),
10087 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010088 format_fib_prefix, &pfx_2001_0_1_s_128);
10089
10090 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_s_96);
Neale Ranns2303cb12018-02-21 04:57:17 -080010091 FIB_TEST(!fib_test_validate_entry(fei,
10092 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10093 1,
10094 &adj_o_3000_1),
10095 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010096 format_fib_prefix, &pfx_2001_1_s_96);
10097 fei = fib_table_lookup_exact_match(0, &pfx_2001_1_1_s_128);
Neale Ranns2303cb12018-02-21 04:57:17 -080010098 FIB_TEST(!fib_test_validate_entry(fei,
10099 FIB_FORW_CHAIN_TYPE_UNICAST_IP6,
10100 1,
10101 &adj_o_3000_1),
10102 "%U via 3000::1",
Neale Ranns89541992017-04-06 04:41:02 -070010103 format_fib_prefix, &pfx_2001_1_1_s_128);
10104
10105 /*
10106 * Cleanup
10107 */
10108 fib_table_entry_delete(0, &pfx_2001_0_1_s_128, FIB_SOURCE_CLI);
10109 fib_table_entry_delete(0, &pfx_2001_1_1_s_128, FIB_SOURCE_CLI);
10110 fib_table_entry_delete(0, &pfx_2001_s_64, FIB_SOURCE_API);
10111 fib_table_entry_delete(0, &pfx_2001_1_s_96, FIB_SOURCE_API);
10112 adj_unlock(ai_3000_1);
10113 adj_unlock(ai_3000_2);
10114
10115 /*
10116 * test no-one left behind
10117 */
10118 FIB_TEST((n_feis == fib_entry_pool_size()), "Entries gone");
10119 FIB_TEST(0 == adj_nbr_db_size(), "All adjacencies removed");
Neale Ranns2303cb12018-02-21 04:57:17 -080010120
10121 return (res);
Neale Ranns89541992017-04-06 04:41:02 -070010122}
10123
Neale Rannsac64b712018-10-08 14:51:11 +000010124static int
10125fib_test_sticky (void)
10126{
10127 fib_route_path_t *r_paths = NULL;
10128 test_main_t *tm = &test_main;
10129 u32 ii, lb_count, pl_count;
10130 dpo_id_t dpo = DPO_INVALID;
10131 fib_node_index_t pl_index;
10132 int res = 0;
10133#define N_PATHS 16
10134
10135 fib_test_lb_bucket_t buckets[N_PATHS];
10136 bfd_session_t bfds[N_PATHS] = {{0}};
10137
10138 lb_count = pool_elts(load_balance_pool);
10139 pl_count = fib_path_list_pool_size();
10140
10141 for (ii = 0; ii < N_PATHS; ii++)
10142 {
10143 ip46_address_t nh = {
10144 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
10145 };
10146 adj_index_t ai;
10147
10148 ai = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
10149 VNET_LINK_IP4,
10150 &nh, tm->hw[0]->sw_if_index);
10151
10152 buckets[ii].type = FT_LB_ADJ;
10153 buckets[ii].adj.adj = ai;
10154
10155 bfds[ii].udp.key.peer_addr = nh;
10156 bfds[ii].udp.key.sw_if_index = tm->hw[0]->sw_if_index;
10157 bfds[ii].hop_type = BFD_HOP_TYPE_SINGLE;
10158 bfds[ii].local_state = BFD_STATE_init;
10159 adj_bfd_notify(BFD_LISTEN_EVENT_CREATE, &bfds[ii]);
10160 bfds[ii].local_state = BFD_STATE_up;
10161 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[ii]);
10162 }
10163
10164 for (ii = 0; ii < N_PATHS; ii++)
10165 {
10166 fib_route_path_t r_path = {
10167 .frp_proto = DPO_PROTO_IP4,
10168 .frp_addr = {
10169 .ip4.as_u32 = clib_host_to_net_u32(0x0a0a0a02 + ii),
10170 },
10171 .frp_sw_if_index = tm->hw[0]->sw_if_index,
10172 .frp_weight = 1,
10173 .frp_fib_index = ~0,
10174 };
10175 vec_add1(r_paths, r_path);
10176 };
10177
10178 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths);
10179 fib_path_list_lock(pl_index);
10180
10181 fib_path_list_contribute_forwarding(pl_index,
10182 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10183 FIB_PATH_LIST_FWD_FLAG_STICKY,
10184 &dpo);
10185
10186 FIB_TEST(!fib_test_validate_lb(&dpo,
10187 16,
10188 &buckets[0],
10189 &buckets[1],
10190 &buckets[2],
10191 &buckets[3],
10192 &buckets[4],
10193 &buckets[5],
10194 &buckets[6],
10195 &buckets[7],
10196 &buckets[8],
10197 &buckets[9],
10198 &buckets[10],
10199 &buckets[11],
10200 &buckets[12],
10201 &buckets[13],
10202 &buckets[14],
10203 &buckets[15]),
10204 "Setup OK");
10205
10206 /* take down paths */
10207 bfds[0].local_state = BFD_STATE_down;
10208 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
10209
10210 fib_path_list_contribute_forwarding(pl_index,
10211 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10212 FIB_PATH_LIST_FWD_FLAG_STICKY,
10213 &dpo);
10214
10215 FIB_TEST(!fib_test_validate_lb(&dpo,
10216 16,
10217 &buckets[1],
10218 &buckets[1],
10219 &buckets[2],
10220 &buckets[3],
10221 &buckets[4],
10222 &buckets[5],
10223 &buckets[6],
10224 &buckets[7],
10225 &buckets[8],
10226 &buckets[9],
10227 &buckets[10],
10228 &buckets[11],
10229 &buckets[12],
10230 &buckets[13],
10231 &buckets[14],
10232 &buckets[15]),
10233 "Failed at shut-down path 0");
10234
10235 bfds[7].local_state = BFD_STATE_down;
10236 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
10237
10238 fib_path_list_contribute_forwarding(pl_index,
10239 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10240 FIB_PATH_LIST_FWD_FLAG_STICKY,
10241 &dpo);
10242
10243 FIB_TEST(!fib_test_validate_lb(&dpo,
10244 16,
10245 &buckets[1],
10246 &buckets[1],
10247 &buckets[2],
10248 &buckets[3],
10249 &buckets[4],
10250 &buckets[5],
10251 &buckets[6],
10252 &buckets[2],
10253 &buckets[8],
10254 &buckets[9],
10255 &buckets[10],
10256 &buckets[11],
10257 &buckets[12],
10258 &buckets[13],
10259 &buckets[14],
10260 &buckets[15]),
10261 "Failed at shut-down path 7");
10262
10263 /* paths back up */
10264 bfds[0].local_state = BFD_STATE_up;
10265 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[0]);
10266 bfds[7].local_state = BFD_STATE_up;
10267 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[7]);
10268
10269 fib_path_list_contribute_forwarding(pl_index,
10270 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10271 FIB_PATH_LIST_FWD_FLAG_STICKY,
10272 &dpo);
10273
10274 FIB_TEST(!fib_test_validate_lb(&dpo,
10275 16,
10276 &buckets[0],
10277 &buckets[1],
10278 &buckets[2],
10279 &buckets[3],
10280 &buckets[4],
10281 &buckets[5],
10282 &buckets[6],
10283 &buckets[7],
10284 &buckets[8],
10285 &buckets[9],
10286 &buckets[10],
10287 &buckets[11],
10288 &buckets[12],
10289 &buckets[13],
10290 &buckets[14],
10291 &buckets[15]),
10292 "recovery OK");
10293
10294 fib_path_list_unlock(pl_index);
10295
10296 /*
10297 * non-power of 2 number of buckets
10298 */
10299 fib_route_path_t *r_paths2 = NULL;
10300
10301 r_paths2 = vec_dup(r_paths);
10302 _vec_len(r_paths2) = 3;
10303
10304 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths2);
10305 fib_path_list_lock(pl_index);
10306
10307 fib_path_list_contribute_forwarding(pl_index,
10308 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10309 FIB_PATH_LIST_FWD_FLAG_STICKY,
10310 &dpo);
10311
10312 FIB_TEST(!fib_test_validate_lb(&dpo,
10313 16,
10314 &buckets[0],
10315 &buckets[0],
10316 &buckets[0],
10317 &buckets[0],
10318 &buckets[0],
10319 &buckets[0],
10320 &buckets[1],
10321 &buckets[1],
10322 &buckets[1],
10323 &buckets[1],
10324 &buckets[1],
10325 &buckets[2],
10326 &buckets[2],
10327 &buckets[2],
10328 &buckets[2],
10329 &buckets[2]),
10330 "non-power of 2");
10331
10332 bfds[1].local_state = BFD_STATE_down;
10333 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10334
10335 fib_path_list_contribute_forwarding(pl_index,
10336 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10337 FIB_PATH_LIST_FWD_FLAG_STICKY,
10338 &dpo);
10339
10340 /*
10341 * path 1's buckets alternate between path 0 and 2
10342 */
10343 FIB_TEST(!fib_test_validate_lb(&dpo,
10344 16,
10345 &buckets[0],
10346 &buckets[0],
10347 &buckets[0],
10348 &buckets[0],
10349 &buckets[0],
10350 &buckets[0],
10351 &buckets[0],
10352 &buckets[2],
10353 &buckets[0],
10354 &buckets[2],
10355 &buckets[0],
10356 &buckets[2],
10357 &buckets[2],
10358 &buckets[2],
10359 &buckets[2],
10360 &buckets[2]),
10361 "non-power of 2");
10362 bfds[1].local_state = BFD_STATE_up;
10363 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10364
10365 fib_path_list_unlock(pl_index);
10366
10367 /*
10368 * unequal cost
10369 */
10370 fib_route_path_t *r_paths3 = NULL;
10371
10372 r_paths3 = vec_dup(r_paths);
10373 _vec_len(r_paths3) = 3;
10374
10375 r_paths3[0].frp_weight = 3;
10376
10377 pl_index = fib_path_list_create(FIB_PATH_LIST_FLAG_SHARED, r_paths3);
10378 fib_path_list_lock(pl_index);
10379
10380 fib_path_list_contribute_forwarding(pl_index,
10381 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10382 FIB_PATH_LIST_FWD_FLAG_STICKY,
10383 &dpo);
10384
10385 FIB_TEST(!fib_test_validate_lb(&dpo,
10386 16,
10387 &buckets[1],
10388 &buckets[1],
10389 &buckets[1],
10390 &buckets[2],
10391 &buckets[2],
10392 &buckets[2],
10393 &buckets[0],
10394 &buckets[0],
10395 &buckets[0],
10396 &buckets[0],
10397 &buckets[0],
10398 &buckets[0],
10399 &buckets[0],
10400 &buckets[0],
10401 &buckets[0],
10402 &buckets[0]),
10403 "UCMP");
10404
10405 bfds[1].local_state = BFD_STATE_down;
10406 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10407
10408 fib_path_list_contribute_forwarding(pl_index,
10409 FIB_FORW_CHAIN_TYPE_UNICAST_IP4,
10410 FIB_PATH_LIST_FWD_FLAG_STICKY,
10411 &dpo);
10412 /* No attempt to Un-equal distribute the down path's buckets */
10413 FIB_TEST(!fib_test_validate_lb(&dpo,
10414 16,
10415 &buckets[2],
10416 &buckets[0],
10417 &buckets[2],
10418 &buckets[2],
10419 &buckets[2],
10420 &buckets[2],
10421 &buckets[0],
10422 &buckets[0],
10423 &buckets[0],
10424 &buckets[0],
10425 &buckets[0],
10426 &buckets[0],
10427 &buckets[0],
10428 &buckets[0],
10429 &buckets[0],
10430 &buckets[0]),
10431 "UCMP");
10432 bfds[1].local_state = BFD_STATE_up;
10433 adj_bfd_notify(BFD_LISTEN_EVENT_UPDATE, &bfds[1]);
10434
10435 dpo_reset(&dpo);
10436 fib_path_list_unlock(pl_index);
10437
10438 vec_free(r_paths);
10439 vec_free(r_paths2);
10440 vec_free(r_paths3);
10441
10442 FIB_TEST(lb_count == pool_elts(load_balance_pool), "no leaked LBs");
10443 FIB_TEST(pl_count == fib_path_list_pool_size(), "no leaked PLs");
10444
10445 return 0;
10446}
10447
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010448static clib_error_t *
Neale Ranns2303cb12018-02-21 04:57:17 -080010449fib_test (vlib_main_t * vm,
10450 unformat_input_t * input,
10451 vlib_cli_command_t * cmd_arg)
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010452{
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010453 int res;
10454
10455 res = 0;
Neale Ranns2303cb12018-02-21 04:57:17 -080010456
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010457 fib_test_mk_intf(4);
10458
Neale Ranns88fc83e2017-04-05 08:11:14 -070010459 if (unformat (input, "debug"))
10460 {
10461 fib_test_do_debug = 1;
10462 }
10463
Neale Ranns2303cb12018-02-21 04:57:17 -080010464 if (unformat (input, "ip4"))
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010465 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010466 res += fib_test_v4();
10467 }
10468 else if (unformat (input, "ip6"))
10469 {
10470 res += fib_test_v6();
10471 }
10472 else if (unformat (input, "ip"))
10473 {
10474 res += fib_test_v4();
10475 res += fib_test_v6();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010476 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010477 else if (unformat (input, "label"))
10478 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010479 res += fib_test_label();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010480 }
10481 else if (unformat (input, "ae"))
10482 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010483 res += fib_test_ae();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010484 }
Neale Ranns57b58602017-07-15 07:37:25 -070010485 else if (unformat (input, "pref"))
10486 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010487 res += fib_test_pref();
Neale Ranns57b58602017-07-15 07:37:25 -070010488 }
Neale Rannsad422ed2016-11-02 14:20:04 +000010489 else if (unformat (input, "lfib"))
10490 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010491 res += lfib_test();
Neale Rannsad422ed2016-11-02 14:20:04 +000010492 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010493 else if (unformat (input, "walk"))
10494 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010495 res += fib_test_walk();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010496 }
Neale Ranns88fc83e2017-04-05 08:11:14 -070010497 else if (unformat (input, "bfd"))
10498 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010499 res += fib_test_bfd();
Neale Ranns88fc83e2017-04-05 08:11:14 -070010500 }
Neale Ranns89541992017-04-06 04:41:02 -070010501 else if (unformat (input, "inherit"))
10502 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010503 res += fib_test_inherit();
Neale Ranns89541992017-04-06 04:41:02 -070010504 }
Neale Rannsac64b712018-10-08 14:51:11 +000010505 else if (unformat (input, "sticky"))
10506 {
10507 res += fib_test_sticky();
10508 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010509 else
10510 {
Neale Ranns2303cb12018-02-21 04:57:17 -080010511 res += fib_test_v4();
10512 res += fib_test_v6();
10513 res += fib_test_ae();
10514 res += fib_test_bfd();
10515 res += fib_test_pref();
10516 res += fib_test_label();
Neale Ranns89541992017-04-06 04:41:02 -070010517 res += fib_test_inherit();
Neale Ranns2303cb12018-02-21 04:57:17 -080010518 res += lfib_test();
Neale Rannsf12a83f2017-04-18 09:09:40 -070010519
10520 /*
10521 * fib-walk process must be disabled in order for the walk tests to work
10522 */
10523 fib_walk_process_disable();
10524 res += fib_test_walk();
10525 fib_walk_process_enable();
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010526 }
10527
Neale Ranns2303cb12018-02-21 04:57:17 -080010528 fflush(NULL);
Neale Ranns0ebe8d72016-12-08 19:48:11 +000010529 if (res)
10530 {
10531 return clib_error_return(0, "FIB Unit Test Failed");
10532 }
10533 else
10534 {
10535 return (NULL);
10536 }
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010537}
10538
10539VLIB_CLI_COMMAND (test_fib_command, static) = {
10540 .path = "test fib",
10541 .short_help = "fib unit tests - DO NOT RUN ON A LIVE SYSTEM",
10542 .function = fib_test,
10543};
10544
Neale Ranns0bfe5d82016-08-25 15:29:12 +010010545clib_error_t *
10546fib_test_init (vlib_main_t *vm)
10547{
10548 return 0;
10549}
10550
10551VLIB_INIT_FUNCTION (fib_test_init);