blob: 8c75e349b8603191d18010544403d8b3448daa65 [file] [log] [blame]
Neale Ranns32e1c012016-11-22 17:07:28 +00001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <vnet/mpls/mpls_types.h>
17
18#include <vnet/mfib/mfib_table.h>
19#include <vnet/mfib/mfib_entry.h>
20#include <vnet/mfib/mfib_signal.h>
21#include <vnet/mfib/ip6_mfib.h>
Neale Rannsa9374df2017-02-02 02:18:18 -080022#include <vnet/fib/fib_path_list.h>
Neale Ranns0f26c5a2017-03-01 15:12:11 -080023#include <vnet/fib/fib_test.h>
24#include <vnet/fib/fib_table.h>
Neale Ranns15002542017-09-10 04:39:11 -070025#include <vnet/fib/mpls_fib.h>
Neale Ranns32e1c012016-11-22 17:07:28 +000026
27#include <vnet/dpo/replicate_dpo.h>
28#include <vnet/adj/adj_mcast.h>
29
30#define MFIB_TEST_I(_cond, _comment, _args...) \
31({ \
32 int _evald = (_cond); \
33 if (!(_evald)) { \
34 fformat(stderr, "FAIL:%d: " _comment "\n", \
35 __LINE__, ##_args); \
Neale Ranns2303cb12018-02-21 04:57:17 -080036 res = 1; \
Neale Ranns32e1c012016-11-22 17:07:28 +000037 } else { \
38 fformat(stderr, "PASS:%d: " _comment "\n", \
39 __LINE__, ##_args); \
40 } \
Neale Ranns2303cb12018-02-21 04:57:17 -080041 res; \
Neale Ranns32e1c012016-11-22 17:07:28 +000042})
43#define MFIB_TEST(_cond, _comment, _args...) \
44{ \
Neale Ranns2303cb12018-02-21 04:57:17 -080045 if (MFIB_TEST_I(_cond, _comment, ##_args)) { \
46 return 1; \
Neale Ranns32e1c012016-11-22 17:07:28 +000047 ASSERT(!("FAIL: " _comment)); \
48 } \
49}
50#define MFIB_TEST_NS(_cond) \
51{ \
Neale Ranns2303cb12018-02-21 04:57:17 -080052 if (MFIB_TEST_I(_cond, "")) { \
53 return 1; \
Neale Ranns32e1c012016-11-22 17:07:28 +000054 ASSERT(!("FAIL: ")); \
55 } \
56}
57
58/**
59 * A 'i'm not fussed is this is not efficient' store of test data
60 */
61typedef struct test_main_t_ {
62 /**
63 * HW if indicies
64 */
65 u32 hw_if_indicies[4];
66 /**
67 * HW interfaces
68 */
69 vnet_hw_interface_t * hw[4];
70
71} test_main_t;
72static test_main_t test_main;
73
74/* fake ethernet device class, distinct from "fake-ethX" */
75static u8 * format_test_interface_name (u8 * s, va_list * args)
76{
77 u32 dev_instance = va_arg (*args, u32);
78 return format (s, "test-eth%d", dev_instance);
79}
80
81static uword dummy_interface_tx (vlib_main_t * vm,
82 vlib_node_runtime_t * node,
83 vlib_frame_t * frame)
84{
85 clib_warning ("you shouldn't be here, leaking buffers...");
86 return frame->n_vectors;
87}
88
89static clib_error_t *
90test_interface_admin_up_down (vnet_main_t * vnm,
91 u32 hw_if_index,
92 u32 flags)
93{
94 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
95 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
96 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
97 return 0;
98}
99
100VNET_DEVICE_CLASS (test_interface_device_class,static) = {
101 .name = "Test interface",
102 .format_device_name = format_test_interface_name,
103 .tx_function = dummy_interface_tx,
104 .admin_up_down_function = test_interface_admin_up_down,
105};
106
107static u8 *hw_address;
108
109static int
110mfib_test_mk_intf (u32 ninterfaces)
111{
112 clib_error_t * error = NULL;
113 test_main_t *tm = &test_main;
114 u8 byte;
Neale Ranns2303cb12018-02-21 04:57:17 -0800115 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000116 u32 i;
117
Neale Ranns2303cb12018-02-21 04:57:17 -0800118 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000119 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
120
121 for (i=0; i<6; i++)
122 {
123 byte = 0xd0+i;
124 vec_add1(hw_address, byte);
125 }
126
127 for (i = 0; i < ninterfaces; i++)
128 {
129 hw_address[5] = i;
130
131 error = ethernet_register_interface(vnet_get_main(),
132 test_interface_device_class.index,
133 i /* instance */,
134 hw_address,
135 &tm->hw_if_indicies[i],
136 /* flag change */ 0);
137
138 MFIB_TEST((NULL == error), "ADD interface %d", i);
139
140 error = vnet_hw_interface_set_flags(vnet_get_main(),
141 tm->hw_if_indicies[i],
142 VNET_HW_INTERFACE_FLAG_LINK_UP);
143 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
144 tm->hw_if_indicies[i]);
145 vec_validate (ip4_main.fib_index_by_sw_if_index,
146 tm->hw[i]->sw_if_index);
147 vec_validate (ip6_main.fib_index_by_sw_if_index,
148 tm->hw[i]->sw_if_index);
149 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
150 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
151
152 vec_validate (ip4_main.mfib_index_by_sw_if_index,
153 tm->hw[i]->sw_if_index);
154 vec_validate (ip6_main.mfib_index_by_sw_if_index,
155 tm->hw[i]->sw_if_index);
156 ip4_main.mfib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
157 ip6_main.mfib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
158
159 error = vnet_sw_interface_set_flags(vnet_get_main(),
160 tm->hw[i]->sw_if_index,
161 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
162 MFIB_TEST((NULL == error), "UP interface %d", i);
163 }
164 /*
165 * re-eval after the inevitable realloc
166 */
167 for (i = 0; i < ninterfaces; i++)
168 {
169 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
170 tm->hw_if_indicies[i]);
171 }
172
Neale Ranns2303cb12018-02-21 04:57:17 -0800173 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000174}
175
176#define MFIB_TEST_REP(_cond, _comment, _args...) \
177{ \
Neale Ranns2303cb12018-02-21 04:57:17 -0800178 if (MFIB_TEST_I(_cond, _comment, ##_args)) { \
179 return (1); \
Neale Ranns32e1c012016-11-22 17:07:28 +0000180 } \
181}
182
183static int
184mfib_test_validate_rep_v (const replicate_t *rep,
185 u16 n_buckets,
Christophe Fontained3c008d2017-10-02 18:10:54 +0200186 va_list *ap)
Neale Ranns32e1c012016-11-22 17:07:28 +0000187{
188 const dpo_id_t *dpo;
189 adj_index_t ai;
190 dpo_type_t dt;
191 int bucket;
Neale Ranns2303cb12018-02-21 04:57:17 -0800192 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000193
Neale Ranns2303cb12018-02-21 04:57:17 -0800194 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000195 MFIB_TEST_REP((n_buckets == rep->rep_n_buckets),
196 "n_buckets = %d", rep->rep_n_buckets);
197
198 for (bucket = 0; bucket < n_buckets; bucket++)
199 {
Christophe Fontained3c008d2017-10-02 18:10:54 +0200200 dt = va_arg(*ap, int); // type promotion
201 ai = va_arg(*ap, adj_index_t);
Neale Ranns32e1c012016-11-22 17:07:28 +0000202 dpo = replicate_get_bucket_i(rep, bucket);
203
204 MFIB_TEST_REP((dt == dpo->dpoi_type),
205 "bucket %d stacks on %U",
206 bucket,
207 format_dpo_type, dpo->dpoi_type);
208
209 if (DPO_RECEIVE != dt)
210 {
211 MFIB_TEST_REP((ai == dpo->dpoi_index),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800212 "bucket %d [exp:%d] stacks on %U",
213 bucket, ai,
Neale Ranns32e1c012016-11-22 17:07:28 +0000214 format_dpo_id, dpo, 0);
215 }
216 }
Neale Ranns2303cb12018-02-21 04:57:17 -0800217 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000218}
219
220static fib_forward_chain_type_t
221fib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
222{
223 switch (proto)
224 {
225 case FIB_PROTOCOL_IP4:
226 return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
227 case FIB_PROTOCOL_IP6:
228 return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
229 default:
230 break;
231 }
232 ASSERT(0);
233 return (0);
234}
235
236
237static int
238mfib_test_entry (fib_node_index_t fei,
239 mfib_entry_flags_t eflags,
Gabriel Ganned71e0fc2017-10-26 10:35:28 +0200240 int n_buckets,
Neale Ranns32e1c012016-11-22 17:07:28 +0000241 ...)
242{
243 const mfib_entry_t *mfe;
244 const replicate_t *rep;
245 mfib_prefix_t pfx;
246 va_list ap;
Neale Ranns05b2bf22017-01-30 06:44:58 -0800247 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000248
249 va_start(ap, n_buckets);
250
Neale Ranns2303cb12018-02-21 04:57:17 -0800251 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000252 mfe = mfib_entry_get(fei);
253 mfib_entry_get_prefix(fei, &pfx);
254
255 MFIB_TEST_REP((eflags == mfe->mfe_flags),
256 "%U has %U expect %U",
257 format_mfib_prefix, &pfx,
258 format_mfib_entry_flags, mfe->mfe_flags,
259 format_mfib_entry_flags, eflags);
260
261 if (0 == n_buckets)
262 {
263 MFIB_TEST_REP((DPO_DROP == mfe->mfe_rep.dpoi_type),
264 "%U links to %U",
265 format_mfib_prefix, &pfx,
266 format_dpo_id, &mfe->mfe_rep, 0);
Neale Ranns32e1c012016-11-22 17:07:28 +0000267 }
268 else
269 {
270 dpo_id_t tmp = DPO_INVALID;
Neale Ranns32e1c012016-11-22 17:07:28 +0000271
272 mfib_entry_contribute_forwarding(
273 fei,
274 fib_forw_chain_type_from_fib_proto(pfx.fp_proto),
275 &tmp);
276 rep = replicate_get(tmp.dpoi_index);
277
278 MFIB_TEST_REP((DPO_REPLICATE == tmp.dpoi_type),
279 "%U links to %U",
280 format_mfib_prefix, &pfx,
281 format_dpo_type, tmp.dpoi_type);
282
Christophe Fontained3c008d2017-10-02 18:10:54 +0200283 res = mfib_test_validate_rep_v(rep, n_buckets, &ap);
Neale Ranns32e1c012016-11-22 17:07:28 +0000284
285 dpo_reset(&tmp);
Neale Ranns32e1c012016-11-22 17:07:28 +0000286 }
Neale Ranns05b2bf22017-01-30 06:44:58 -0800287
288 va_end(ap);
289
290 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000291}
292
293static int
294mfib_test_entry_itf (fib_node_index_t fei,
295 u32 sw_if_index,
296 mfib_itf_flags_t flags)
297{
298 const mfib_entry_t *mfe;
299 const mfib_itf_t *mfi;
300 mfib_prefix_t pfx;
Neale Ranns2303cb12018-02-21 04:57:17 -0800301 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000302
Neale Ranns2303cb12018-02-21 04:57:17 -0800303 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000304 mfe = mfib_entry_get(fei);
305 mfi = mfib_entry_get_itf(mfe, sw_if_index);
306 mfib_entry_get_prefix(fei, &pfx);
307
308 MFIB_TEST_REP((NULL != mfi),
309 "%U has interface %d",
310 format_mfib_prefix, &pfx, sw_if_index);
311
312 MFIB_TEST_REP((flags == mfi->mfi_flags),
313 "%U interface %d has flags %U expect %U",
314 format_mfib_prefix, &pfx, sw_if_index,
315 format_mfib_itf_flags, flags,
316 format_mfib_itf_flags, mfi->mfi_flags);
317
Neale Ranns2303cb12018-02-21 04:57:17 -0800318 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000319}
320
321static int
322mfib_test_entry_no_itf (fib_node_index_t fei,
323 u32 sw_if_index)
324{
325 const mfib_entry_t *mfe;
326 const mfib_itf_t *mfi;
327 mfib_prefix_t pfx;
Neale Ranns2303cb12018-02-21 04:57:17 -0800328 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000329
Neale Ranns2303cb12018-02-21 04:57:17 -0800330 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000331 mfe = mfib_entry_get(fei);
332 mfi = mfib_entry_get_itf(mfe, sw_if_index);
333 mfib_entry_get_prefix(fei, &pfx);
334
335 MFIB_TEST_REP((NULL == mfi),
336 "%U has no interface %d",
337 format_mfib_prefix, &pfx, sw_if_index);
338
Neale Ranns2303cb12018-02-21 04:57:17 -0800339 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000340}
341
342static int
343mfib_test_i (fib_protocol_t PROTO,
344 vnet_link_t LINKT,
345 const mfib_prefix_t *pfx_no_forward,
346 const mfib_prefix_t *pfx_s_g,
347 const mfib_prefix_t *pfx_star_g_1,
348 const mfib_prefix_t *pfx_star_g_2,
349 const mfib_prefix_t *pfx_star_g_3,
350 const mfib_prefix_t *pfx_star_g_slash_m)
351{
352 fib_node_index_t mfei, mfei_dflt, mfei_no_f, mfei_s_g, mfei_g_1, mfei_g_2, mfei_g_3, mfei_g_m;
Neale Rannsa9374df2017-02-02 02:18:18 -0800353 u32 fib_index, n_entries, n_itfs, n_reps, n_pls;
Neale Ranns32e1c012016-11-22 17:07:28 +0000354 fib_node_index_t ai_1, ai_2, ai_3;
355 test_main_t *tm;
Neale Ranns2303cb12018-02-21 04:57:17 -0800356 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000357
358 mfib_prefix_t all_1s;
359 memset(&all_1s, 0xfd, sizeof(all_1s));
360
Neale Ranns2303cb12018-02-21 04:57:17 -0800361 res = 0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000362 n_entries = pool_elts(mfib_entry_pool);
363 n_itfs = pool_elts(mfib_itf_pool);
364 n_reps = pool_elts(replicate_pool);
Neale Rannsa9374df2017-02-02 02:18:18 -0800365 n_pls = fib_path_list_pool_size();
Neale Ranns32e1c012016-11-22 17:07:28 +0000366 tm = &test_main;
367
368 ai_1 = adj_mcast_add_or_lock(PROTO,
369 LINKT,
370 tm->hw[1]->sw_if_index);
371 ai_2 = adj_mcast_add_or_lock(PROTO,
372 LINKT,
373 tm->hw[2]->sw_if_index);
374 ai_3 = adj_mcast_add_or_lock(PROTO,
375 LINKT,
376 tm->hw[3]->sw_if_index);
377
378 MFIB_TEST(3 == adj_mcast_db_size(), "3 MCAST adjs");
379
380 /* Find or create FIB table 11 */
Neale Ranns15002542017-09-10 04:39:11 -0700381 fib_index = mfib_table_find_or_create_and_lock(PROTO, 11, MFIB_SOURCE_API);
Neale Ranns32e1c012016-11-22 17:07:28 +0000382
383 mfib_prefix_t pfx_dft = {
384 .fp_len = 0,
385 .fp_proto = PROTO,
386 };
387 mfei_dflt = mfib_table_lookup_exact_match(fib_index, &pfx_dft);
388 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_dflt, "(*,*) presnet");
Neale Ranns2303cb12018-02-21 04:57:17 -0800389 MFIB_TEST(!mfib_test_entry(mfei_dflt,
390 MFIB_ENTRY_FLAG_DROP,
391 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000392 "(*,*) no replcaitions");
393
394 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_dflt, "(*,*) presnet");
Neale Ranns2303cb12018-02-21 04:57:17 -0800395 MFIB_TEST(!mfib_test_entry(mfei_dflt,
396 MFIB_ENTRY_FLAG_DROP,
397 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000398 "(*,*) no replcaitions");
399
400
401 fib_route_path_t path_via_if0 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700402 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000403 .frp_addr = zero_addr,
404 .frp_sw_if_index = tm->hw[0]->sw_if_index,
405 .frp_fib_index = ~0,
406 .frp_weight = 0,
407 .frp_flags = 0,
408 };
409
410 mfib_table_entry_path_update(fib_index,
411 pfx_no_forward,
412 MFIB_SOURCE_API,
413 &path_via_if0,
414 MFIB_ITF_FLAG_ACCEPT);
415
416 mfei_no_f = mfib_table_lookup_exact_match(fib_index, pfx_no_forward);
Neale Ranns2303cb12018-02-21 04:57:17 -0800417 MFIB_TEST(!mfib_test_entry(mfei_no_f,
418 MFIB_ENTRY_FLAG_NONE,
419 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000420 "%U no replcaitions",
421 format_mfib_prefix, pfx_no_forward);
Neale Ranns2303cb12018-02-21 04:57:17 -0800422 MFIB_TEST_NS(!mfib_test_entry_itf(mfei_no_f, tm->hw[0]->sw_if_index,
423 MFIB_ITF_FLAG_ACCEPT));
Neale Ranns32e1c012016-11-22 17:07:28 +0000424
425 fib_route_path_t path_via_if1 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700426 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000427 .frp_addr = zero_addr,
428 .frp_sw_if_index = tm->hw[1]->sw_if_index,
429 .frp_fib_index = ~0,
430 .frp_weight = 0,
431 .frp_flags = 0,
432 };
433 fib_route_path_t path_via_if2 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700434 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000435 .frp_addr = zero_addr,
436 .frp_sw_if_index = tm->hw[2]->sw_if_index,
437 .frp_fib_index = ~0,
438 .frp_weight = 0,
439 .frp_flags = 0,
440 };
441 fib_route_path_t path_via_if3 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700442 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000443 .frp_addr = zero_addr,
444 .frp_sw_if_index = tm->hw[3]->sw_if_index,
445 .frp_fib_index = ~0,
446 .frp_weight = 0,
447 .frp_flags = 0,
448 };
449 fib_route_path_t path_for_us = {
Neale Rannsda78f952017-05-24 09:15:43 -0700450 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000451 .frp_addr = zero_addr,
452 .frp_sw_if_index = 0xffffffff,
453 .frp_fib_index = ~0,
454 .frp_weight = 0,
455 .frp_flags = FIB_ROUTE_PATH_LOCAL,
456 };
457
458 /*
459 * An (S,G) with 1 accepting and 3 forwarding paths
460 */
461 mfib_table_entry_path_update(fib_index,
462 pfx_s_g,
463 MFIB_SOURCE_API,
464 &path_via_if0,
465 MFIB_ITF_FLAG_ACCEPT);
466 mfib_table_entry_path_update(fib_index,
467 pfx_s_g,
468 MFIB_SOURCE_API,
469 &path_via_if1,
470 MFIB_ITF_FLAG_FORWARD);
471 mfib_table_entry_path_update(fib_index,
472 pfx_s_g,
473 MFIB_SOURCE_API,
474 &path_via_if2,
475 MFIB_ITF_FLAG_FORWARD);
476 mfib_table_entry_path_update(fib_index,
477 pfx_s_g,
478 MFIB_SOURCE_API,
479 &path_via_if3,
480 (MFIB_ITF_FLAG_FORWARD |
481 MFIB_ITF_FLAG_NEGATE_SIGNAL));
482
483 mfei_s_g = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
484
485 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_s_g,
486 "%U present",
487 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800488 MFIB_TEST(!mfib_test_entry(mfei_s_g,
489 MFIB_ENTRY_FLAG_NONE,
490 3,
491 DPO_ADJACENCY_MCAST, ai_1,
492 DPO_ADJACENCY_MCAST, ai_2,
493 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000494 "%U replicate ok",
495 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800496 MFIB_TEST_NS(!mfib_test_entry_itf(mfei_s_g, tm->hw[0]->sw_if_index,
497 MFIB_ITF_FLAG_ACCEPT));
498 MFIB_TEST_NS(!mfib_test_entry_itf(mfei_s_g, tm->hw[1]->sw_if_index,
499 MFIB_ITF_FLAG_FORWARD));
500 MFIB_TEST_NS(!mfib_test_entry_itf(mfei_s_g, tm->hw[2]->sw_if_index,
501 MFIB_ITF_FLAG_FORWARD));
502 MFIB_TEST_NS(!mfib_test_entry_itf(mfei_s_g, tm->hw[3]->sw_if_index,
503 (MFIB_ITF_FLAG_FORWARD |
504 MFIB_ITF_FLAG_NEGATE_SIGNAL)));
Neale Ranns32e1c012016-11-22 17:07:28 +0000505
506 /*
507 * A (*,G), which the same G as the (S,G).
508 * different paths. test our LPM.
509 */
510 mfei_g_1 = mfib_table_entry_path_update(fib_index,
511 pfx_star_g_1,
512 MFIB_SOURCE_API,
513 &path_via_if0,
514 MFIB_ITF_FLAG_ACCEPT);
515 mfib_table_entry_path_update(fib_index,
516 pfx_star_g_1,
517 MFIB_SOURCE_API,
518 &path_via_if1,
519 MFIB_ITF_FLAG_FORWARD);
520
521 /*
522 * test we find the *,G and S,G via LPM and exact matches
523 */
524 mfei = mfib_table_lookup_exact_match(fib_index,
525 pfx_star_g_1);
526 MFIB_TEST(mfei == mfei_g_1,
527 "%U found via exact match",
528 format_mfib_prefix, pfx_star_g_1);
Neale Ranns2303cb12018-02-21 04:57:17 -0800529 MFIB_TEST(!mfib_test_entry(mfei,
530 MFIB_ENTRY_FLAG_NONE,
531 1,
532 DPO_ADJACENCY_MCAST, ai_1),
Neale Ranns32e1c012016-11-22 17:07:28 +0000533 "%U replicate ok",
534 format_mfib_prefix, pfx_star_g_1);
535
536 mfei = mfib_table_lookup(fib_index,
537 pfx_star_g_1);
538 MFIB_TEST(mfei == mfei_g_1,
539 "%U found via LP match",
540 format_mfib_prefix, pfx_star_g_1);
541
Neale Ranns2303cb12018-02-21 04:57:17 -0800542 MFIB_TEST(!mfib_test_entry(mfei,
543 MFIB_ENTRY_FLAG_NONE,
544 1,
545 DPO_ADJACENCY_MCAST, ai_1),
Neale Ranns32e1c012016-11-22 17:07:28 +0000546 "%U replicate ok",
547 format_mfib_prefix, pfx_star_g_1);
548
549 mfei = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
550 MFIB_TEST(mfei == mfei_s_g,
551 "%U found via exact match",
552 format_mfib_prefix, pfx_s_g);
553
Neale Ranns2303cb12018-02-21 04:57:17 -0800554 MFIB_TEST(!mfib_test_entry(mfei,
555 MFIB_ENTRY_FLAG_NONE,
556 3,
557 DPO_ADJACENCY_MCAST, ai_1,
558 DPO_ADJACENCY_MCAST, ai_2,
559 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000560 "%U replicate OK",
561 format_mfib_prefix, pfx_s_g);
562 mfei = mfib_table_lookup(fib_index, pfx_s_g);
563 MFIB_TEST(mfei == mfei_s_g,
564 "%U found via LP match",
565 format_mfib_prefix, pfx_s_g);
566
Neale Ranns2303cb12018-02-21 04:57:17 -0800567 MFIB_TEST(!mfib_test_entry(mfei,
568 MFIB_ENTRY_FLAG_NONE,
569 3,
570 DPO_ADJACENCY_MCAST, ai_1,
571 DPO_ADJACENCY_MCAST, ai_2,
572 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000573 "%U replicate OK",
574 format_mfib_prefix, pfx_s_g);
575
576 /*
577 * A (*,G/m), which the same root G as the (*,G).
578 * different paths. test our LPM.
579 */
580 mfei_g_m = mfib_table_entry_path_update(fib_index,
581 pfx_star_g_slash_m,
582 MFIB_SOURCE_API,
583 &path_via_if2,
584 MFIB_ITF_FLAG_ACCEPT);
585 mfib_table_entry_path_update(fib_index,
586 pfx_star_g_slash_m,
587 MFIB_SOURCE_API,
588 &path_via_if3,
589 MFIB_ITF_FLAG_FORWARD);
590
591 /*
592 * test we find the (*,G/m), (*,G) and (S,G) via LPM and exact matches
593 */
594 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_1);
595 MFIB_TEST((mfei_g_1 == mfei),
596 "%U found via DP LPM: %d",
597 format_mfib_prefix, pfx_star_g_1, mfei);
598
Neale Ranns2303cb12018-02-21 04:57:17 -0800599 MFIB_TEST(!mfib_test_entry(mfei,
600 MFIB_ENTRY_FLAG_NONE,
601 1,
602 DPO_ADJACENCY_MCAST, ai_1),
Neale Ranns32e1c012016-11-22 17:07:28 +0000603 "%U replicate ok",
604 format_mfib_prefix, pfx_star_g_1);
605
606 mfei = mfib_table_lookup(fib_index, pfx_star_g_1);
607
Neale Ranns2303cb12018-02-21 04:57:17 -0800608 MFIB_TEST(!mfib_test_entry(mfei,
609 MFIB_ENTRY_FLAG_NONE,
610 1,
611 DPO_ADJACENCY_MCAST, ai_1),
Neale Ranns32e1c012016-11-22 17:07:28 +0000612 "%U replicate ok",
613 format_mfib_prefix, pfx_star_g_1);
614
615 mfei = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
616
Neale Ranns2303cb12018-02-21 04:57:17 -0800617 MFIB_TEST(!mfib_test_entry(mfei,
618 MFIB_ENTRY_FLAG_NONE,
619 3,
620 DPO_ADJACENCY_MCAST, ai_1,
621 DPO_ADJACENCY_MCAST, ai_2,
622 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000623 "%U replicate OK",
624 format_mfib_prefix, pfx_s_g);
625 mfei = mfib_table_lookup(fib_index, pfx_s_g);
626
Neale Ranns2303cb12018-02-21 04:57:17 -0800627 MFIB_TEST(!mfib_test_entry(mfei,
628 MFIB_ENTRY_FLAG_NONE,
629 3,
630 DPO_ADJACENCY_MCAST, ai_1,
631 DPO_ADJACENCY_MCAST, ai_2,
632 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000633 "%U replicate OK",
634 format_mfib_prefix, pfx_s_g);
635
636 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_slash_m);
637 MFIB_TEST(mfei = mfei_g_m,
638 "%U Found via exact match",
639 format_mfib_prefix, pfx_star_g_slash_m);
Neale Ranns2303cb12018-02-21 04:57:17 -0800640 MFIB_TEST(!mfib_test_entry(mfei,
641 MFIB_ENTRY_FLAG_NONE,
642 1,
643 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000644 "%U replicate OK",
645 format_mfib_prefix, pfx_star_g_slash_m);
646 MFIB_TEST(mfei_g_m == mfib_table_lookup(fib_index, pfx_star_g_slash_m),
647 "%U found via LPM",
648 format_mfib_prefix, pfx_star_g_slash_m);
649
650 /*
651 * Add a for-us path
652 */
653 mfei = mfib_table_entry_path_update(fib_index,
654 pfx_s_g,
655 MFIB_SOURCE_API,
656 &path_for_us,
657 MFIB_ITF_FLAG_FORWARD);
658
Neale Ranns2303cb12018-02-21 04:57:17 -0800659 MFIB_TEST(!mfib_test_entry(mfei,
660 MFIB_ENTRY_FLAG_NONE,
661 4,
662 DPO_ADJACENCY_MCAST, ai_1,
663 DPO_ADJACENCY_MCAST, ai_2,
664 DPO_ADJACENCY_MCAST, ai_3,
665 DPO_RECEIVE, 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000666 "%U replicate OK",
667 format_mfib_prefix, pfx_s_g);
668
669 /*
670 * remove a for-us path
671 */
672 mfib_table_entry_path_remove(fib_index,
673 pfx_s_g,
674 MFIB_SOURCE_API,
675 &path_for_us);
676
Neale Ranns2303cb12018-02-21 04:57:17 -0800677 MFIB_TEST(!mfib_test_entry(mfei,
678 MFIB_ENTRY_FLAG_NONE,
679 3,
680 DPO_ADJACENCY_MCAST, ai_1,
681 DPO_ADJACENCY_MCAST, ai_2,
682 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000683 "%U replicate OK",
684 format_mfib_prefix, pfx_s_g);
685
686 /*
687 * update an existing forwarding path to be only accepting
688 * - expect it to be removed from the replication set.
689 */
690 mfib_table_entry_path_update(fib_index,
691 pfx_s_g,
692 MFIB_SOURCE_API,
693 &path_via_if3,
694 MFIB_ITF_FLAG_ACCEPT);
695
Neale Ranns2303cb12018-02-21 04:57:17 -0800696 MFIB_TEST(!mfib_test_entry(mfei,
697 MFIB_ENTRY_FLAG_NONE,
698 2,
699 DPO_ADJACENCY_MCAST, ai_1,
700 DPO_ADJACENCY_MCAST, ai_2),
Neale Ranns32e1c012016-11-22 17:07:28 +0000701 "%U replicate OK",
702 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800703 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
704 MFIB_ITF_FLAG_ACCEPT));
705 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
706 MFIB_ITF_FLAG_FORWARD));
707 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
708 MFIB_ITF_FLAG_FORWARD));
709 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[3]->sw_if_index,
710 MFIB_ITF_FLAG_ACCEPT));
Neale Ranns32e1c012016-11-22 17:07:28 +0000711 /*
712 * Make the path forwarding again
713 * - expect it to be added back to the replication set
714 */
715 mfib_table_entry_path_update(fib_index,
716 pfx_s_g,
717 MFIB_SOURCE_API,
718 &path_via_if3,
719 (MFIB_ITF_FLAG_FORWARD |
720 MFIB_ITF_FLAG_ACCEPT |
721 MFIB_ITF_FLAG_NEGATE_SIGNAL));
722
723 mfei = mfib_table_lookup_exact_match(fib_index,
724 pfx_s_g);
725
Neale Ranns2303cb12018-02-21 04:57:17 -0800726 MFIB_TEST(!mfib_test_entry(mfei,
727 MFIB_ENTRY_FLAG_NONE,
728 3,
729 DPO_ADJACENCY_MCAST, ai_1,
730 DPO_ADJACENCY_MCAST, ai_2,
731 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000732 "%U replicate OK",
733 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800734 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
735 MFIB_ITF_FLAG_ACCEPT));
736 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
737 MFIB_ITF_FLAG_FORWARD));
738 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
739 MFIB_ITF_FLAG_FORWARD));
740 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[3]->sw_if_index,
741 (MFIB_ITF_FLAG_FORWARD |
742 MFIB_ITF_FLAG_ACCEPT |
743 MFIB_ITF_FLAG_NEGATE_SIGNAL)));
Neale Ranns32e1c012016-11-22 17:07:28 +0000744
745 /*
746 * update flags on the entry
747 */
748 mfib_table_entry_update(fib_index,
749 pfx_s_g,
750 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800751 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000752 MFIB_ENTRY_FLAG_SIGNAL);
Neale Ranns2303cb12018-02-21 04:57:17 -0800753 MFIB_TEST(!mfib_test_entry(mfei,
754 MFIB_ENTRY_FLAG_SIGNAL,
755 3,
756 DPO_ADJACENCY_MCAST, ai_1,
757 DPO_ADJACENCY_MCAST, ai_2,
758 DPO_ADJACENCY_MCAST, ai_3),
Neale Ranns32e1c012016-11-22 17:07:28 +0000759 "%U replicate OK",
760 format_mfib_prefix, pfx_s_g);
761
762 /*
763 * remove paths
764 */
765 mfib_table_entry_path_remove(fib_index,
766 pfx_s_g,
767 MFIB_SOURCE_API,
768 &path_via_if3);
769
Neale Ranns2303cb12018-02-21 04:57:17 -0800770 MFIB_TEST(!mfib_test_entry(mfei,
771 MFIB_ENTRY_FLAG_SIGNAL,
772 2,
773 DPO_ADJACENCY_MCAST, ai_1,
774 DPO_ADJACENCY_MCAST, ai_2),
Neale Ranns32e1c012016-11-22 17:07:28 +0000775 "%U replicate OK",
776 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800777 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
778 MFIB_ITF_FLAG_ACCEPT));
779 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
780 MFIB_ITF_FLAG_FORWARD));
781 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
782 MFIB_ITF_FLAG_FORWARD));
783 MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
Neale Ranns32e1c012016-11-22 17:07:28 +0000784
785 mfib_table_entry_path_remove(fib_index,
786 pfx_s_g,
787 MFIB_SOURCE_API,
788 &path_via_if1);
789
Neale Ranns2303cb12018-02-21 04:57:17 -0800790 MFIB_TEST(!mfib_test_entry(mfei,
791 MFIB_ENTRY_FLAG_SIGNAL,
792 1,
793 DPO_ADJACENCY_MCAST, ai_2),
Neale Ranns32e1c012016-11-22 17:07:28 +0000794 "%U replicate OK",
795 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800796 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
797 MFIB_ITF_FLAG_ACCEPT));
798 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
799 MFIB_ITF_FLAG_FORWARD));
800 MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
Neale Ranns32e1c012016-11-22 17:07:28 +0000801
802 /*
803 * remove the accpeting only interface
804 */
805 mfib_table_entry_path_remove(fib_index,
806 pfx_s_g,
807 MFIB_SOURCE_API,
808 &path_via_if0);
809
Neale Ranns2303cb12018-02-21 04:57:17 -0800810 MFIB_TEST(!mfib_test_entry(mfei,
811 MFIB_ENTRY_FLAG_SIGNAL,
812 1,
813 DPO_ADJACENCY_MCAST, ai_2),
Neale Ranns32e1c012016-11-22 17:07:28 +0000814 "%U replicate OK",
815 format_mfib_prefix, pfx_s_g);
Neale Ranns2303cb12018-02-21 04:57:17 -0800816 MFIB_TEST_NS(!mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
817 MFIB_ITF_FLAG_FORWARD));
818 MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[0]->sw_if_index));
819 MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[1]->sw_if_index));
820 MFIB_TEST_NS(!mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
Neale Ranns32e1c012016-11-22 17:07:28 +0000821
822 /*
823 * remove the last path, the entry still has flags so it remains
824 */
825 mfib_table_entry_path_remove(fib_index,
826 pfx_s_g,
827 MFIB_SOURCE_API,
828 &path_via_if2);
829
Neale Ranns2303cb12018-02-21 04:57:17 -0800830 MFIB_TEST(!mfib_test_entry(mfei,
831 MFIB_ENTRY_FLAG_SIGNAL,
832 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000833 "%U no replications",
834 format_mfib_prefix, pfx_s_g);
835
836 /*
837 * update flags on the entry
838 */
839 mfib_table_entry_update(fib_index,
840 pfx_s_g,
841 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800842 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000843 (MFIB_ENTRY_FLAG_SIGNAL |
844 MFIB_ENTRY_FLAG_CONNECTED));
Neale Ranns2303cb12018-02-21 04:57:17 -0800845 MFIB_TEST(!mfib_test_entry(mfei,
846 (MFIB_ENTRY_FLAG_SIGNAL |
847 MFIB_ENTRY_FLAG_CONNECTED),
848 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000849 "%U no replications",
850 format_mfib_prefix, pfx_s_g);
851
852 /*
853 * An entry with a NS interface
854 */
855 mfei_g_2 = mfib_table_entry_path_update(fib_index,
856 pfx_star_g_2,
857 MFIB_SOURCE_API,
858 &path_via_if0,
859 (MFIB_ITF_FLAG_ACCEPT |
860 MFIB_ITF_FLAG_NEGATE_SIGNAL));
Neale Ranns2303cb12018-02-21 04:57:17 -0800861 MFIB_TEST(!mfib_test_entry(mfei_g_2,
862 MFIB_ENTRY_FLAG_NONE,
863 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000864 "%U No replications",
865 format_mfib_prefix, pfx_star_g_2);
866
867 /*
868 * Simulate a signal from the data-plane
869 */
870 {
871 mfib_entry_t *mfe;
872 mfib_itf_t *mfi;
873
874 mfe = mfib_entry_get(mfei_g_2);
875 mfi = mfib_entry_get_itf(mfe, path_via_if0.frp_sw_if_index);
876
877 mfib_signal_push(mfe, mfi, NULL);
878 }
879
880 /*
881 * An entry with a NS interface
882 */
883 mfei_g_3 = mfib_table_entry_path_update(fib_index,
884 pfx_star_g_3,
885 MFIB_SOURCE_API,
886 &path_via_if0,
887 (MFIB_ITF_FLAG_ACCEPT |
888 MFIB_ITF_NEGATE_SIGNAL));
Neale Ranns2303cb12018-02-21 04:57:17 -0800889 MFIB_TEST(!mfib_test_entry(mfei_g_3,
890 MFIB_ENTRY_FLAG_NONE,
891 0),
Neale Ranns32e1c012016-11-22 17:07:28 +0000892 "%U No replications",
893 format_mfib_prefix, pfx_star_g_3);
894
895 /*
896 * Simulate a signal from the data-plane
897 */
898 {
899 mfib_entry_t *mfe;
900 mfib_itf_t *mfi;
901
902 mfe = mfib_entry_get(mfei_g_3);
903 mfi = mfib_entry_get_itf(mfe, path_via_if0.frp_sw_if_index);
904
905 mfib_signal_push(mfe, mfi, NULL);
906 }
907
908 if (FIB_PROTOCOL_IP6 == PROTO)
909 {
910 /*
911 * All the entries are present. let's ensure we can find them all
912 * via exact and longest prefix matches.
913 */
914 /*
915 * A source address we will never match
916 */
917 ip6_address_t src = {
918 .as_u64[0] = clib_host_to_net_u64(0x3001000000000000),
919 .as_u64[1] = clib_host_to_net_u64(0xffffffffffffffff),
920 };
921
922 /*
923 * Find the (*,G/m)
924 */
925 MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2(
Neale Ranns2303cb12018-02-21 04:57:17 -0800926 ip6_mfib_get(fib_index),
927 &src,
928 &pfx_star_g_slash_m->fp_grp_addr.ip6)),
Neale Ranns32e1c012016-11-22 17:07:28 +0000929 "%U found via DP LPM grp=%U",
930 format_mfib_prefix, pfx_star_g_slash_m,
931 format_ip6_address, &pfx_star_g_slash_m->fp_grp_addr.ip6);
932
933 ip6_address_t tmp = pfx_star_g_slash_m->fp_grp_addr.ip6;
934 tmp.as_u8[15] = 0xff;
935
936 MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2(
Neale Ranns2303cb12018-02-21 04:57:17 -0800937 ip6_mfib_get(fib_index),
938 &pfx_s_g->fp_src_addr.ip6,
939 &tmp)),
Neale Ranns32e1c012016-11-22 17:07:28 +0000940 "%U found via DP LPM grp=%U",
941 format_mfib_prefix, pfx_star_g_slash_m,
942 format_ip6_address, &tmp);
943
944 /*
945 * Find the (S,G).
946 */
947 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
948 &pfx_s_g->fp_src_addr.ip6,
949 &pfx_s_g->fp_grp_addr.ip6);
950 MFIB_TEST((mfei_s_g == mfei),
951 "%U found via DP LPM: %d",
952 format_mfib_prefix, pfx_s_g, mfei);
953
954 /*
955 * Find the 3 (*,G) s
956 */
957 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
958 &src,
959 &pfx_star_g_1->fp_grp_addr.ip6);
960 MFIB_TEST((mfei_g_1 == mfei),
961 "%U found via DP LPM: %d",
962 format_mfib_prefix, pfx_star_g_1, mfei);
963 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
964 &src,
965 &pfx_star_g_2->fp_grp_addr.ip6);
966 MFIB_TEST((mfei_g_2 == mfei),
967 "%U found via DP LPM: %d",
968 format_mfib_prefix, pfx_star_g_2, mfei);
969 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
970 &src,
971 &pfx_star_g_3->fp_grp_addr.ip6);
972 MFIB_TEST((mfei_g_3 == mfei),
973 "%U found via DP LPM: %d",
974 format_mfib_prefix, pfx_star_g_3, mfei);
975 }
976
977 /*
978 * remove flags on the entry. This is the last of the
979 * state associated with the entry, so now it goes.
980 */
981 mfib_table_entry_update(fib_index,
982 pfx_s_g,
983 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800984 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000985 MFIB_ENTRY_FLAG_NONE);
986 mfei = mfib_table_lookup_exact_match(fib_index,
987 pfx_s_g);
988 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
989 "%U gone",
990 format_mfib_prefix, pfx_s_g);
991
992 /*
993 * remove the last path on the no forward entry - the last entry
994 */
995 mfib_table_entry_path_remove(fib_index,
996 pfx_no_forward,
997 MFIB_SOURCE_API,
998 &path_via_if0);
999
1000 mfei = mfib_table_lookup_exact_match(fib_index, pfx_no_forward);
1001 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1002 "%U gone",
1003 format_mfib_prefix, pfx_no_forward);
1004
1005 /*
1006 * hard delete the (*,232.1.1.1)
1007 */
1008 mfib_table_entry_delete(fib_index,
1009 pfx_star_g_1,
1010 MFIB_SOURCE_API);
1011
1012 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_1);
1013 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1014 "%U gone",
1015 format_mfib_prefix, pfx_star_g_1);
1016 /*
1017 * remove the entry whilst the signal is pending
1018 */
1019 mfib_table_entry_delete(fib_index,
1020 pfx_star_g_2,
1021 MFIB_SOURCE_API);
1022
1023 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_2);
1024 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1025 "%U Gone",
1026 format_mfib_prefix, pfx_star_g_2);
1027 mfib_table_entry_delete(fib_index,
1028 pfx_star_g_3,
1029 MFIB_SOURCE_API);
1030
1031 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_3);
1032 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1033 "%U Gone",
1034 format_mfib_prefix, pfx_star_g_3);
1035
1036 mfib_table_entry_delete(fib_index,
1037 pfx_star_g_slash_m,
1038 MFIB_SOURCE_API);
1039
1040 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_slash_m);
1041 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1042 "%U Gone",
1043 format_mfib_prefix, pfx_star_g_slash_m);
1044
1045 /*
Neale Rannsa9374df2017-02-02 02:18:18 -08001046 * Add a prefix as a special/exclusive route
1047 */
1048 dpo_id_t td = DPO_INVALID;
1049 index_t repi = replicate_create(1, fib_proto_to_dpo(PROTO));
1050
1051 dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_2);
1052 replicate_set_bucket(repi, 0, &td);
1053
1054 mfei = mfib_table_entry_special_add(fib_index,
1055 pfx_star_g_3,
1056 MFIB_SOURCE_SRv6,
1057 MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
1058 repi);
Neale Ranns2303cb12018-02-21 04:57:17 -08001059 MFIB_TEST(!mfib_test_entry(mfei,
1060 (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
1061 MFIB_ENTRY_FLAG_EXCLUSIVE),
1062 1,
1063 DPO_ADJACENCY_MCAST, ai_2),
Neale Rannsa9374df2017-02-02 02:18:18 -08001064 "%U exclusive replicate OK",
1065 format_mfib_prefix, pfx_star_g_3);
1066
1067 /*
1068 * update a special/exclusive route
1069 */
1070 index_t repi2 = replicate_create(1, fib_proto_to_dpo(PROTO));
1071
1072 dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_1);
1073 replicate_set_bucket(repi2, 0, &td);
1074
1075 mfei = mfib_table_entry_special_add(fib_index,
1076 pfx_star_g_3,
1077 MFIB_SOURCE_SRv6,
1078 MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
1079 repi2);
Neale Ranns2303cb12018-02-21 04:57:17 -08001080 MFIB_TEST(!mfib_test_entry(mfei,
1081 (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
1082 MFIB_ENTRY_FLAG_EXCLUSIVE),
1083 1,
1084 DPO_ADJACENCY_MCAST, ai_1),
Neale Rannsa9374df2017-02-02 02:18:18 -08001085 "%U exclusive update replicate OK",
1086 format_mfib_prefix, pfx_star_g_3);
1087
1088 mfib_table_entry_delete(fib_index,
1089 pfx_star_g_3,
1090 MFIB_SOURCE_SRv6);
1091 dpo_reset(&td);
1092
1093 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001094 * A Multicast LSP. This a mLDP head-end
1095 */
1096 fib_node_index_t ai_mpls_10_10_10_1, lfei;
1097 ip46_address_t nh_10_10_10_1 = {
1098 .ip4 = {
1099 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1100 },
1101 };
1102 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
1103 VNET_LINK_MPLS,
1104 &nh_10_10_10_1,
1105 tm->hw[0]->sw_if_index);
1106
1107 fib_prefix_t pfx_3500 = {
1108 .fp_len = 21,
1109 .fp_proto = FIB_PROTOCOL_MPLS,
1110 .fp_label = 3500,
1111 .fp_eos = MPLS_EOS,
1112 .fp_payload_proto = DPO_PROTO_IP4,
1113 };
1114 fib_test_rep_bucket_t mc_0 = {
1115 .type = FT_REP_LABEL_O_ADJ,
1116 .label_o_adj = {
1117 .adj = ai_mpls_10_10_10_1,
1118 .label = 3300,
1119 .eos = MPLS_EOS,
1120 },
1121 };
Neale Ranns31ed7442018-02-23 05:29:09 -08001122 fib_mpls_label_t *l3300 = NULL, fml3300 = {
1123 .fml_value = 3300,
1124 };
1125 vec_add1(l3300, fml3300);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001126
1127 /*
1128 * MPLS enable an interface so we get the MPLS table created
1129 */
Neale Ranns2297af02017-09-12 09:45:04 -07001130 mpls_table_create(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API, NULL);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001131 mpls_sw_interface_enable_disable(&mpls_main,
1132 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07001133 1, 0);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001134
1135 lfei = fib_table_entry_update_one_path(0, // default MPLS Table
1136 &pfx_3500,
1137 FIB_SOURCE_API,
1138 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07001139 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001140 &nh_10_10_10_1,
1141 tm->hw[0]->sw_if_index,
1142 ~0, // invalid fib index
1143 1,
1144 l3300,
1145 FIB_ROUTE_PATH_FLAG_NONE);
Neale Ranns2303cb12018-02-21 04:57:17 -08001146 MFIB_TEST(!fib_test_validate_entry(lfei,
1147 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
1148 1,
1149 &mc_0),
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001150 "3500 via replicate over 10.10.10.1");
1151
1152 /*
1153 * An (S,G) that resolves via the mLDP head-end
1154 */
1155 fib_route_path_t path_via_mldp = {
Neale Rannsda78f952017-05-24 09:15:43 -07001156 .frp_proto = DPO_PROTO_MPLS,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001157 .frp_local_label = pfx_3500.fp_label,
1158 .frp_eos = MPLS_EOS,
1159 .frp_sw_if_index = 0xffffffff,
1160 .frp_fib_index = 0,
1161 .frp_weight = 1,
1162 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
1163 };
1164 dpo_id_t mldp_dpo = DPO_INVALID;
1165
1166 fib_entry_contribute_forwarding(lfei,
1167 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
1168 &mldp_dpo);
1169
1170 mfei = mfib_table_entry_path_update(fib_index,
1171 pfx_s_g,
1172 MFIB_SOURCE_API,
1173 &path_via_mldp,
1174 MFIB_ITF_FLAG_FORWARD);
1175
Neale Ranns2303cb12018-02-21 04:57:17 -08001176 MFIB_TEST(!mfib_test_entry(mfei,
1177 MFIB_ENTRY_FLAG_NONE,
1178 1,
1179 DPO_REPLICATE, mldp_dpo.dpoi_index),
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001180 "%U over-mLDP replicate OK",
1181 format_mfib_prefix, pfx_s_g);
1182
1183 /*
1184 * add a for-us path. this tests two types of non-attached paths on one entry
1185 */
1186 mfei = mfib_table_entry_path_update(fib_index,
1187 pfx_s_g,
1188 MFIB_SOURCE_API,
1189 &path_for_us,
1190 MFIB_ITF_FLAG_FORWARD);
Neale Ranns2303cb12018-02-21 04:57:17 -08001191 MFIB_TEST(!mfib_test_entry(mfei,
1192 MFIB_ENTRY_FLAG_NONE,
1193 2,
1194 DPO_REPLICATE, mldp_dpo.dpoi_index,
1195 DPO_RECEIVE, 0),
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001196 "%U mLDP+for-us replicate OK",
1197 format_mfib_prefix, pfx_s_g);
1198
1199 mfib_table_entry_delete(fib_index,
1200 pfx_s_g,
1201 MFIB_SOURCE_API);
1202 fib_table_entry_delete(0,
1203 &pfx_3500,
1204 FIB_SOURCE_API);
1205 dpo_reset(&mldp_dpo);
1206
1207 /*
Neale Ranns32e1c012016-11-22 17:07:28 +00001208 * Unlock the table - it's the last lock so should be gone thereafter
1209 */
Neale Ranns15002542017-09-10 04:39:11 -07001210 mfib_table_unlock(fib_index, PROTO, MFIB_SOURCE_API);
Neale Ranns32e1c012016-11-22 17:07:28 +00001211
1212 MFIB_TEST((FIB_NODE_INDEX_INVALID ==
1213 mfib_table_find(PROTO, fib_index)),
1214 "MFIB table %d gone", fib_index);
1215
1216 adj_unlock(ai_1);
1217 adj_unlock(ai_2);
1218 adj_unlock(ai_3);
1219
1220 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001221 * MPLS disable the interface
1222 */
1223 mpls_sw_interface_enable_disable(&mpls_main,
1224 tm->hw[0]->sw_if_index,
Neale Ranns15002542017-09-10 04:39:11 -07001225 0, 0);
1226 mpls_table_delete(MPLS_FIB_DEFAULT_TABLE_ID, FIB_SOURCE_API);
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001227
1228 /*
Neale Ranns32e1c012016-11-22 17:07:28 +00001229 * test we've leaked no resources
1230 */
1231 MFIB_TEST(0 == adj_mcast_db_size(), "%d MCAST adjs", adj_mcast_db_size());
Neale Rannsa9374df2017-02-02 02:18:18 -08001232 MFIB_TEST(n_pls == fib_path_list_pool_size(), "%d=%d path-lists",
1233 n_pls, fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001234 MFIB_TEST(n_reps == pool_elts(replicate_pool), "%d=%d replicates",
1235 n_reps, pool_elts(replicate_pool));
1236 MFIB_TEST(n_entries == pool_elts(mfib_entry_pool),
1237 " No more entries %d!=%d",
1238 n_entries, pool_elts(mfib_entry_pool));
1239 MFIB_TEST(n_itfs == pool_elts(mfib_itf_pool),
1240 " No more Interfaces %d!=%d",
1241 n_itfs, pool_elts(mfib_itf_pool));
1242
Neale Ranns2303cb12018-02-21 04:57:17 -08001243 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +00001244}
1245
1246static int
1247mfib_test_v4 (void)
1248{
1249 const mfib_prefix_t pfx_224_s_8 = {
1250 .fp_len = 8,
1251 .fp_proto = FIB_PROTOCOL_IP4,
1252 .fp_grp_addr = {
1253 .ip4.as_u32 = clib_host_to_net_u32(0xe0000000),
1254 }
1255 };
1256 const mfib_prefix_t pfx_1_1_1_1_c_239_1_1_1 = {
1257 .fp_len = 64,
1258 .fp_proto = FIB_PROTOCOL_IP4,
1259 .fp_grp_addr = {
1260 .ip4.as_u32 = clib_host_to_net_u32(0xef010101),
1261 },
1262 .fp_src_addr = {
1263 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1264 },
1265 };
1266 const mfib_prefix_t pfx_239_1_1_1 = {
1267 .fp_len = 32,
1268 .fp_proto = FIB_PROTOCOL_IP4,
1269 .fp_grp_addr = {
1270 .ip4.as_u32 = clib_host_to_net_u32(0xef010101),
1271 },
1272 .fp_src_addr = {
1273 .ip4.as_u32 = 0,
1274 },
1275 };
1276 const mfib_prefix_t pfx_239_1_1_2 = {
1277 .fp_len = 32,
1278 .fp_proto = FIB_PROTOCOL_IP4,
1279 .fp_grp_addr = {
1280 .ip4.as_u32 = clib_host_to_net_u32(0xef010102),
1281 },
1282 .fp_src_addr = {
1283 .ip4.as_u32 = 0,
1284 },
1285 };
1286 const mfib_prefix_t pfx_239_1_1_3 = {
1287 .fp_len = 32,
1288 .fp_proto = FIB_PROTOCOL_IP4,
1289 .fp_grp_addr = {
1290 .ip4.as_u32 = clib_host_to_net_u32(0xef010103),
1291 },
1292 .fp_src_addr = {
1293 .ip4.as_u32 = 0,
1294 },
1295 };
1296 const mfib_prefix_t pfx_239 = {
1297 .fp_len = 8,
1298 .fp_proto = FIB_PROTOCOL_IP4,
1299 .fp_grp_addr = {
1300 .ip4.as_u32 = clib_host_to_net_u32(0xef000000),
1301 },
1302 .fp_src_addr = {
1303 .ip4.as_u32 = 0,
1304 },
1305 };
1306
1307 return (mfib_test_i(FIB_PROTOCOL_IP4,
1308 VNET_LINK_IP4,
1309 &pfx_224_s_8,
1310 &pfx_1_1_1_1_c_239_1_1_1,
1311 &pfx_239_1_1_1,
1312 &pfx_239_1_1_2,
1313 &pfx_239_1_1_3,
1314 &pfx_239));
1315}
1316
1317static int
1318mfib_test_v6 (void)
1319{
1320 const mfib_prefix_t pfx_ffd_s_12 = {
1321 .fp_len = 12,
1322 .fp_proto = FIB_PROTOCOL_IP6,
1323 .fp_grp_addr = {
1324 .ip6.as_u64[0] = clib_host_to_net_u64(0xffd0000000000000),
1325 }
1326 };
1327 const mfib_prefix_t pfx_2001_1_c_ff_1 = {
1328 .fp_len = 256,
1329 .fp_proto = FIB_PROTOCOL_IP6,
1330 .fp_grp_addr = {
1331 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1332 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1333 },
1334 .fp_src_addr = {
1335 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
1336 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1337 },
1338 };
1339 const mfib_prefix_t pfx_ff_1 = {
1340 .fp_len = 128,
1341 .fp_proto = FIB_PROTOCOL_IP6,
1342 .fp_grp_addr = {
1343 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1344 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1345 },
1346 };
1347 const mfib_prefix_t pfx_ff_2 = {
1348 .fp_len = 128,
1349 .fp_proto = FIB_PROTOCOL_IP6,
1350 .fp_grp_addr = {
1351 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1352 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000002),
1353 },
1354 };
1355 const mfib_prefix_t pfx_ff_3 = {
1356 /*
1357 * this is the ALL DHCP routers address
1358 */
1359 .fp_len = 128,
1360 .fp_proto = FIB_PROTOCOL_IP6,
1361 .fp_grp_addr = {
1362 .ip6.as_u64[0] = clib_host_to_net_u64(0xff02000100000000),
1363 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000002),
1364 },
1365 };
1366 const mfib_prefix_t pfx_ff = {
1367 .fp_len = 16,
1368 .fp_proto = FIB_PROTOCOL_IP6,
1369 .fp_grp_addr = {
1370 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1371 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000000),
1372 },
1373 };
1374
1375 return (mfib_test_i(FIB_PROTOCOL_IP6,
1376 VNET_LINK_IP6,
1377 &pfx_ffd_s_12,
1378 &pfx_2001_1_c_ff_1,
1379 &pfx_ff_1,
1380 &pfx_ff_2,
1381 &pfx_ff_3,
1382 &pfx_ff));
1383}
1384
1385static clib_error_t *
1386mfib_test (vlib_main_t * vm,
1387 unformat_input_t * input,
1388 vlib_cli_command_t * cmd_arg)
1389{
1390 int res = 0;
1391
1392 res += mfib_test_mk_intf(4);
1393 res += mfib_test_v4();
1394 res += mfib_test_v6();
1395
1396 if (res)
1397 {
1398 return clib_error_return(0, "MFIB Unit Test Failed");
1399 }
1400 else
1401 {
1402 return (NULL);
1403 }
1404}
1405
1406VLIB_CLI_COMMAND (test_fib_command, static) = {
1407 .path = "test mfib",
Neale Rannsa9374df2017-02-02 02:18:18 -08001408 .short_help = "mfib unit tests - DO NOT RUN ON A LIVE SYSTEM",
Neale Ranns32e1c012016-11-22 17:07:28 +00001409 .function = mfib_test,
1410};
1411
1412clib_error_t *
1413mfib_test_init (vlib_main_t *vm)
1414{
1415 return 0;
1416}
1417
1418VLIB_INIT_FUNCTION (mfib_test_init);