blob: 57787eca641b915b8e9046708434169b1a5502c7 [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 Ranns32e1c012016-11-22 17:07:28 +000025
26#include <vnet/dpo/replicate_dpo.h>
27#include <vnet/adj/adj_mcast.h>
28
29#define MFIB_TEST_I(_cond, _comment, _args...) \
30({ \
31 int _evald = (_cond); \
32 if (!(_evald)) { \
33 fformat(stderr, "FAIL:%d: " _comment "\n", \
34 __LINE__, ##_args); \
35 } else { \
36 fformat(stderr, "PASS:%d: " _comment "\n", \
37 __LINE__, ##_args); \
38 } \
39 _evald; \
40})
41#define MFIB_TEST(_cond, _comment, _args...) \
42{ \
43 if (!MFIB_TEST_I(_cond, _comment, ##_args)) { \
44 return 1;\
45 ASSERT(!("FAIL: " _comment)); \
46 } \
47}
48#define MFIB_TEST_NS(_cond) \
49{ \
50 if (!MFIB_TEST_I(_cond, "")) { \
51 return 1;\
52 ASSERT(!("FAIL: ")); \
53 } \
54}
55
56/**
57 * A 'i'm not fussed is this is not efficient' store of test data
58 */
59typedef struct test_main_t_ {
60 /**
61 * HW if indicies
62 */
63 u32 hw_if_indicies[4];
64 /**
65 * HW interfaces
66 */
67 vnet_hw_interface_t * hw[4];
68
69} test_main_t;
70static test_main_t test_main;
71
72/* fake ethernet device class, distinct from "fake-ethX" */
73static u8 * format_test_interface_name (u8 * s, va_list * args)
74{
75 u32 dev_instance = va_arg (*args, u32);
76 return format (s, "test-eth%d", dev_instance);
77}
78
79static uword dummy_interface_tx (vlib_main_t * vm,
80 vlib_node_runtime_t * node,
81 vlib_frame_t * frame)
82{
83 clib_warning ("you shouldn't be here, leaking buffers...");
84 return frame->n_vectors;
85}
86
87static clib_error_t *
88test_interface_admin_up_down (vnet_main_t * vnm,
89 u32 hw_if_index,
90 u32 flags)
91{
92 u32 hw_flags = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
93 VNET_HW_INTERFACE_FLAG_LINK_UP : 0;
94 vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
95 return 0;
96}
97
98VNET_DEVICE_CLASS (test_interface_device_class,static) = {
99 .name = "Test interface",
100 .format_device_name = format_test_interface_name,
101 .tx_function = dummy_interface_tx,
102 .admin_up_down_function = test_interface_admin_up_down,
103};
104
105static u8 *hw_address;
106
107static int
108mfib_test_mk_intf (u32 ninterfaces)
109{
110 clib_error_t * error = NULL;
111 test_main_t *tm = &test_main;
112 u8 byte;
113 u32 i;
114
115 ASSERT(ninterfaces <= ARRAY_LEN(tm->hw_if_indicies));
116
117 for (i=0; i<6; i++)
118 {
119 byte = 0xd0+i;
120 vec_add1(hw_address, byte);
121 }
122
123 for (i = 0; i < ninterfaces; i++)
124 {
125 hw_address[5] = i;
126
127 error = ethernet_register_interface(vnet_get_main(),
128 test_interface_device_class.index,
129 i /* instance */,
130 hw_address,
131 &tm->hw_if_indicies[i],
132 /* flag change */ 0);
133
134 MFIB_TEST((NULL == error), "ADD interface %d", i);
135
136 error = vnet_hw_interface_set_flags(vnet_get_main(),
137 tm->hw_if_indicies[i],
138 VNET_HW_INTERFACE_FLAG_LINK_UP);
139 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
140 tm->hw_if_indicies[i]);
141 vec_validate (ip4_main.fib_index_by_sw_if_index,
142 tm->hw[i]->sw_if_index);
143 vec_validate (ip6_main.fib_index_by_sw_if_index,
144 tm->hw[i]->sw_if_index);
145 ip4_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
146 ip6_main.fib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
147
148 vec_validate (ip4_main.mfib_index_by_sw_if_index,
149 tm->hw[i]->sw_if_index);
150 vec_validate (ip6_main.mfib_index_by_sw_if_index,
151 tm->hw[i]->sw_if_index);
152 ip4_main.mfib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
153 ip6_main.mfib_index_by_sw_if_index[tm->hw[i]->sw_if_index] = 0;
154
155 error = vnet_sw_interface_set_flags(vnet_get_main(),
156 tm->hw[i]->sw_if_index,
157 VNET_SW_INTERFACE_FLAG_ADMIN_UP);
158 MFIB_TEST((NULL == error), "UP interface %d", i);
159 }
160 /*
161 * re-eval after the inevitable realloc
162 */
163 for (i = 0; i < ninterfaces; i++)
164 {
165 tm->hw[i] = vnet_get_hw_interface(vnet_get_main(),
166 tm->hw_if_indicies[i]);
167 }
168
169 return (0);
170}
171
172#define MFIB_TEST_REP(_cond, _comment, _args...) \
173{ \
174 if (!MFIB_TEST_I(_cond, _comment, ##_args)) { \
175 return (0); \
176 } \
177}
178
179static int
180mfib_test_validate_rep_v (const replicate_t *rep,
181 u16 n_buckets,
182 va_list ap)
183{
184 const dpo_id_t *dpo;
185 adj_index_t ai;
186 dpo_type_t dt;
187 int bucket;
188
189 MFIB_TEST_REP((n_buckets == rep->rep_n_buckets),
190 "n_buckets = %d", rep->rep_n_buckets);
191
192 for (bucket = 0; bucket < n_buckets; bucket++)
193 {
194 dt = va_arg(ap, int); // type promotion
195 ai = va_arg(ap, adj_index_t);
196 dpo = replicate_get_bucket_i(rep, bucket);
197
198 MFIB_TEST_REP((dt == dpo->dpoi_type),
199 "bucket %d stacks on %U",
200 bucket,
201 format_dpo_type, dpo->dpoi_type);
202
203 if (DPO_RECEIVE != dt)
204 {
205 MFIB_TEST_REP((ai == dpo->dpoi_index),
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800206 "bucket %d [exp:%d] stacks on %U",
207 bucket, ai,
Neale Ranns32e1c012016-11-22 17:07:28 +0000208 format_dpo_id, dpo, 0);
209 }
210 }
211 return (!0);
212}
213
214static fib_forward_chain_type_t
215fib_forw_chain_type_from_fib_proto (fib_protocol_t proto)
216{
217 switch (proto)
218 {
219 case FIB_PROTOCOL_IP4:
220 return (FIB_FORW_CHAIN_TYPE_UNICAST_IP4);
221 case FIB_PROTOCOL_IP6:
222 return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
223 default:
224 break;
225 }
226 ASSERT(0);
227 return (0);
228}
229
230
231static int
232mfib_test_entry (fib_node_index_t fei,
233 mfib_entry_flags_t eflags,
234 u16 n_buckets,
235 ...)
236{
237 const mfib_entry_t *mfe;
238 const replicate_t *rep;
239 mfib_prefix_t pfx;
240 va_list ap;
Neale Ranns05b2bf22017-01-30 06:44:58 -0800241 int res;
Neale Ranns32e1c012016-11-22 17:07:28 +0000242
243 va_start(ap, n_buckets);
244
245 mfe = mfib_entry_get(fei);
246 mfib_entry_get_prefix(fei, &pfx);
247
248 MFIB_TEST_REP((eflags == mfe->mfe_flags),
249 "%U has %U expect %U",
250 format_mfib_prefix, &pfx,
251 format_mfib_entry_flags, mfe->mfe_flags,
252 format_mfib_entry_flags, eflags);
253
254 if (0 == n_buckets)
255 {
256 MFIB_TEST_REP((DPO_DROP == mfe->mfe_rep.dpoi_type),
257 "%U links to %U",
258 format_mfib_prefix, &pfx,
259 format_dpo_id, &mfe->mfe_rep, 0);
Neale Ranns05b2bf22017-01-30 06:44:58 -0800260 res = !0;
Neale Ranns32e1c012016-11-22 17:07:28 +0000261 }
262 else
263 {
264 dpo_id_t tmp = DPO_INVALID;
Neale Ranns32e1c012016-11-22 17:07:28 +0000265
266 mfib_entry_contribute_forwarding(
267 fei,
268 fib_forw_chain_type_from_fib_proto(pfx.fp_proto),
269 &tmp);
270 rep = replicate_get(tmp.dpoi_index);
271
272 MFIB_TEST_REP((DPO_REPLICATE == tmp.dpoi_type),
273 "%U links to %U",
274 format_mfib_prefix, &pfx,
275 format_dpo_type, tmp.dpoi_type);
276
277 res = mfib_test_validate_rep_v(rep, n_buckets, ap);
278
279 dpo_reset(&tmp);
Neale Ranns32e1c012016-11-22 17:07:28 +0000280 }
Neale Ranns05b2bf22017-01-30 06:44:58 -0800281
282 va_end(ap);
283
284 return (res);
Neale Ranns32e1c012016-11-22 17:07:28 +0000285}
286
287static int
288mfib_test_entry_itf (fib_node_index_t fei,
289 u32 sw_if_index,
290 mfib_itf_flags_t flags)
291{
292 const mfib_entry_t *mfe;
293 const mfib_itf_t *mfi;
294 mfib_prefix_t pfx;
295
296 mfe = mfib_entry_get(fei);
297 mfi = mfib_entry_get_itf(mfe, sw_if_index);
298 mfib_entry_get_prefix(fei, &pfx);
299
300 MFIB_TEST_REP((NULL != mfi),
301 "%U has interface %d",
302 format_mfib_prefix, &pfx, sw_if_index);
303
304 MFIB_TEST_REP((flags == mfi->mfi_flags),
305 "%U interface %d has flags %U expect %U",
306 format_mfib_prefix, &pfx, sw_if_index,
307 format_mfib_itf_flags, flags,
308 format_mfib_itf_flags, mfi->mfi_flags);
309
310 return (!0);
311}
312
313static int
314mfib_test_entry_no_itf (fib_node_index_t fei,
315 u32 sw_if_index)
316{
317 const mfib_entry_t *mfe;
318 const mfib_itf_t *mfi;
319 mfib_prefix_t pfx;
320
321 mfe = mfib_entry_get(fei);
322 mfi = mfib_entry_get_itf(mfe, sw_if_index);
323 mfib_entry_get_prefix(fei, &pfx);
324
325 MFIB_TEST_REP((NULL == mfi),
326 "%U has no interface %d",
327 format_mfib_prefix, &pfx, sw_if_index);
328
329 return (!0);
330}
331
332static int
333mfib_test_i (fib_protocol_t PROTO,
334 vnet_link_t LINKT,
335 const mfib_prefix_t *pfx_no_forward,
336 const mfib_prefix_t *pfx_s_g,
337 const mfib_prefix_t *pfx_star_g_1,
338 const mfib_prefix_t *pfx_star_g_2,
339 const mfib_prefix_t *pfx_star_g_3,
340 const mfib_prefix_t *pfx_star_g_slash_m)
341{
342 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 -0800343 u32 fib_index, n_entries, n_itfs, n_reps, n_pls;
Neale Ranns32e1c012016-11-22 17:07:28 +0000344 fib_node_index_t ai_1, ai_2, ai_3;
345 test_main_t *tm;
346
347 mfib_prefix_t all_1s;
348 memset(&all_1s, 0xfd, sizeof(all_1s));
349
350 n_entries = pool_elts(mfib_entry_pool);
351 n_itfs = pool_elts(mfib_itf_pool);
352 n_reps = pool_elts(replicate_pool);
Neale Rannsa9374df2017-02-02 02:18:18 -0800353 n_pls = fib_path_list_pool_size();
Neale Ranns32e1c012016-11-22 17:07:28 +0000354 tm = &test_main;
355
356 ai_1 = adj_mcast_add_or_lock(PROTO,
357 LINKT,
358 tm->hw[1]->sw_if_index);
359 ai_2 = adj_mcast_add_or_lock(PROTO,
360 LINKT,
361 tm->hw[2]->sw_if_index);
362 ai_3 = adj_mcast_add_or_lock(PROTO,
363 LINKT,
364 tm->hw[3]->sw_if_index);
365
366 MFIB_TEST(3 == adj_mcast_db_size(), "3 MCAST adjs");
367
368 /* Find or create FIB table 11 */
369 fib_index = mfib_table_find_or_create_and_lock(PROTO, 11);
370
371 mfib_prefix_t pfx_dft = {
372 .fp_len = 0,
373 .fp_proto = PROTO,
374 };
375 mfei_dflt = mfib_table_lookup_exact_match(fib_index, &pfx_dft);
376 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_dflt, "(*,*) presnet");
377 MFIB_TEST(mfib_test_entry(mfei_dflt,
378 MFIB_ENTRY_FLAG_DROP,
379 0),
380 "(*,*) no replcaitions");
381
382 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_dflt, "(*,*) presnet");
383 MFIB_TEST(mfib_test_entry(mfei_dflt,
384 MFIB_ENTRY_FLAG_DROP,
385 0),
386 "(*,*) no replcaitions");
387
388
389 fib_route_path_t path_via_if0 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700390 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000391 .frp_addr = zero_addr,
392 .frp_sw_if_index = tm->hw[0]->sw_if_index,
393 .frp_fib_index = ~0,
394 .frp_weight = 0,
395 .frp_flags = 0,
396 };
397
398 mfib_table_entry_path_update(fib_index,
399 pfx_no_forward,
400 MFIB_SOURCE_API,
401 &path_via_if0,
402 MFIB_ITF_FLAG_ACCEPT);
403
404 mfei_no_f = mfib_table_lookup_exact_match(fib_index, pfx_no_forward);
405 MFIB_TEST(mfib_test_entry(mfei_no_f,
406 MFIB_ENTRY_FLAG_NONE,
407 0),
408 "%U no replcaitions",
409 format_mfib_prefix, pfx_no_forward);
410 MFIB_TEST_NS(mfib_test_entry_itf(mfei_no_f, tm->hw[0]->sw_if_index,
411 MFIB_ITF_FLAG_ACCEPT));
412
413 fib_route_path_t path_via_if1 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700414 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000415 .frp_addr = zero_addr,
416 .frp_sw_if_index = tm->hw[1]->sw_if_index,
417 .frp_fib_index = ~0,
418 .frp_weight = 0,
419 .frp_flags = 0,
420 };
421 fib_route_path_t path_via_if2 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700422 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000423 .frp_addr = zero_addr,
424 .frp_sw_if_index = tm->hw[2]->sw_if_index,
425 .frp_fib_index = ~0,
426 .frp_weight = 0,
427 .frp_flags = 0,
428 };
429 fib_route_path_t path_via_if3 = {
Neale Rannsda78f952017-05-24 09:15:43 -0700430 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000431 .frp_addr = zero_addr,
432 .frp_sw_if_index = tm->hw[3]->sw_if_index,
433 .frp_fib_index = ~0,
434 .frp_weight = 0,
435 .frp_flags = 0,
436 };
437 fib_route_path_t path_for_us = {
Neale Rannsda78f952017-05-24 09:15:43 -0700438 .frp_proto = fib_proto_to_dpo(PROTO),
Neale Ranns32e1c012016-11-22 17:07:28 +0000439 .frp_addr = zero_addr,
440 .frp_sw_if_index = 0xffffffff,
441 .frp_fib_index = ~0,
442 .frp_weight = 0,
443 .frp_flags = FIB_ROUTE_PATH_LOCAL,
444 };
445
446 /*
447 * An (S,G) with 1 accepting and 3 forwarding paths
448 */
449 mfib_table_entry_path_update(fib_index,
450 pfx_s_g,
451 MFIB_SOURCE_API,
452 &path_via_if0,
453 MFIB_ITF_FLAG_ACCEPT);
454 mfib_table_entry_path_update(fib_index,
455 pfx_s_g,
456 MFIB_SOURCE_API,
457 &path_via_if1,
458 MFIB_ITF_FLAG_FORWARD);
459 mfib_table_entry_path_update(fib_index,
460 pfx_s_g,
461 MFIB_SOURCE_API,
462 &path_via_if2,
463 MFIB_ITF_FLAG_FORWARD);
464 mfib_table_entry_path_update(fib_index,
465 pfx_s_g,
466 MFIB_SOURCE_API,
467 &path_via_if3,
468 (MFIB_ITF_FLAG_FORWARD |
469 MFIB_ITF_FLAG_NEGATE_SIGNAL));
470
471 mfei_s_g = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
472
473 MFIB_TEST(FIB_NODE_INDEX_INVALID != mfei_s_g,
474 "%U present",
475 format_mfib_prefix, pfx_s_g);
476 MFIB_TEST(mfib_test_entry(mfei_s_g,
477 MFIB_ENTRY_FLAG_NONE,
478 3,
479 DPO_ADJACENCY_MCAST, ai_1,
480 DPO_ADJACENCY_MCAST, ai_2,
481 DPO_ADJACENCY_MCAST, ai_3),
482 "%U replicate ok",
483 format_mfib_prefix, pfx_s_g);
484 MFIB_TEST_NS(mfib_test_entry_itf(mfei_s_g, tm->hw[0]->sw_if_index,
485 MFIB_ITF_FLAG_ACCEPT));
486 MFIB_TEST_NS(mfib_test_entry_itf(mfei_s_g, tm->hw[1]->sw_if_index,
487 MFIB_ITF_FLAG_FORWARD));
488 MFIB_TEST_NS(mfib_test_entry_itf(mfei_s_g, tm->hw[2]->sw_if_index,
489 MFIB_ITF_FLAG_FORWARD));
490 MFIB_TEST_NS(mfib_test_entry_itf(mfei_s_g, tm->hw[3]->sw_if_index,
491 (MFIB_ITF_FLAG_FORWARD |
492 MFIB_ITF_FLAG_NEGATE_SIGNAL)));
493
494 /*
495 * A (*,G), which the same G as the (S,G).
496 * different paths. test our LPM.
497 */
498 mfei_g_1 = mfib_table_entry_path_update(fib_index,
499 pfx_star_g_1,
500 MFIB_SOURCE_API,
501 &path_via_if0,
502 MFIB_ITF_FLAG_ACCEPT);
503 mfib_table_entry_path_update(fib_index,
504 pfx_star_g_1,
505 MFIB_SOURCE_API,
506 &path_via_if1,
507 MFIB_ITF_FLAG_FORWARD);
508
509 /*
510 * test we find the *,G and S,G via LPM and exact matches
511 */
512 mfei = mfib_table_lookup_exact_match(fib_index,
513 pfx_star_g_1);
514 MFIB_TEST(mfei == mfei_g_1,
515 "%U found via exact match",
516 format_mfib_prefix, pfx_star_g_1);
517 MFIB_TEST(mfib_test_entry(mfei,
518 MFIB_ENTRY_FLAG_NONE,
519 1,
520 DPO_ADJACENCY_MCAST, ai_1),
521 "%U replicate ok",
522 format_mfib_prefix, pfx_star_g_1);
523
524 mfei = mfib_table_lookup(fib_index,
525 pfx_star_g_1);
526 MFIB_TEST(mfei == mfei_g_1,
527 "%U found via LP match",
528 format_mfib_prefix, pfx_star_g_1);
529
530 MFIB_TEST(mfib_test_entry(mfei,
531 MFIB_ENTRY_FLAG_NONE,
532 1,
533 DPO_ADJACENCY_MCAST, ai_1),
534 "%U replicate ok",
535 format_mfib_prefix, pfx_star_g_1);
536
537 mfei = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
538 MFIB_TEST(mfei == mfei_s_g,
539 "%U found via exact match",
540 format_mfib_prefix, pfx_s_g);
541
542 MFIB_TEST(mfib_test_entry(mfei,
543 MFIB_ENTRY_FLAG_NONE,
544 3,
545 DPO_ADJACENCY_MCAST, ai_1,
546 DPO_ADJACENCY_MCAST, ai_2,
547 DPO_ADJACENCY_MCAST, ai_3),
548 "%U replicate OK",
549 format_mfib_prefix, pfx_s_g);
550 mfei = mfib_table_lookup(fib_index, pfx_s_g);
551 MFIB_TEST(mfei == mfei_s_g,
552 "%U found via LP match",
553 format_mfib_prefix, pfx_s_g);
554
555 MFIB_TEST(mfib_test_entry(mfei,
556 MFIB_ENTRY_FLAG_NONE,
557 3,
558 DPO_ADJACENCY_MCAST, ai_1,
559 DPO_ADJACENCY_MCAST, ai_2,
560 DPO_ADJACENCY_MCAST, ai_3),
561 "%U replicate OK",
562 format_mfib_prefix, pfx_s_g);
563
564 /*
565 * A (*,G/m), which the same root G as the (*,G).
566 * different paths. test our LPM.
567 */
568 mfei_g_m = mfib_table_entry_path_update(fib_index,
569 pfx_star_g_slash_m,
570 MFIB_SOURCE_API,
571 &path_via_if2,
572 MFIB_ITF_FLAG_ACCEPT);
573 mfib_table_entry_path_update(fib_index,
574 pfx_star_g_slash_m,
575 MFIB_SOURCE_API,
576 &path_via_if3,
577 MFIB_ITF_FLAG_FORWARD);
578
579 /*
580 * test we find the (*,G/m), (*,G) and (S,G) via LPM and exact matches
581 */
582 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_1);
583 MFIB_TEST((mfei_g_1 == mfei),
584 "%U found via DP LPM: %d",
585 format_mfib_prefix, pfx_star_g_1, mfei);
586
587 MFIB_TEST(mfib_test_entry(mfei,
588 MFIB_ENTRY_FLAG_NONE,
589 1,
590 DPO_ADJACENCY_MCAST, ai_1),
591 "%U replicate ok",
592 format_mfib_prefix, pfx_star_g_1);
593
594 mfei = mfib_table_lookup(fib_index, pfx_star_g_1);
595
596 MFIB_TEST(mfib_test_entry(mfei,
597 MFIB_ENTRY_FLAG_NONE,
598 1,
599 DPO_ADJACENCY_MCAST, ai_1),
600 "%U replicate ok",
601 format_mfib_prefix, pfx_star_g_1);
602
603 mfei = mfib_table_lookup_exact_match(fib_index, pfx_s_g);
604
605 MFIB_TEST(mfib_test_entry(mfei,
606 MFIB_ENTRY_FLAG_NONE,
607 3,
608 DPO_ADJACENCY_MCAST, ai_1,
609 DPO_ADJACENCY_MCAST, ai_2,
610 DPO_ADJACENCY_MCAST, ai_3),
611 "%U replicate OK",
612 format_mfib_prefix, pfx_s_g);
613 mfei = mfib_table_lookup(fib_index, pfx_s_g);
614
615 MFIB_TEST(mfib_test_entry(mfei,
616 MFIB_ENTRY_FLAG_NONE,
617 3,
618 DPO_ADJACENCY_MCAST, ai_1,
619 DPO_ADJACENCY_MCAST, ai_2,
620 DPO_ADJACENCY_MCAST, ai_3),
621 "%U replicate OK",
622 format_mfib_prefix, pfx_s_g);
623
624 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_slash_m);
625 MFIB_TEST(mfei = mfei_g_m,
626 "%U Found via exact match",
627 format_mfib_prefix, pfx_star_g_slash_m);
628 MFIB_TEST(mfib_test_entry(mfei,
629 MFIB_ENTRY_FLAG_NONE,
630 1,
631 DPO_ADJACENCY_MCAST, ai_3),
632 "%U replicate OK",
633 format_mfib_prefix, pfx_star_g_slash_m);
634 MFIB_TEST(mfei_g_m == mfib_table_lookup(fib_index, pfx_star_g_slash_m),
635 "%U found via LPM",
636 format_mfib_prefix, pfx_star_g_slash_m);
637
638 /*
639 * Add a for-us path
640 */
641 mfei = mfib_table_entry_path_update(fib_index,
642 pfx_s_g,
643 MFIB_SOURCE_API,
644 &path_for_us,
645 MFIB_ITF_FLAG_FORWARD);
646
647 MFIB_TEST(mfib_test_entry(mfei,
648 MFIB_ENTRY_FLAG_NONE,
649 4,
650 DPO_ADJACENCY_MCAST, ai_1,
651 DPO_ADJACENCY_MCAST, ai_2,
652 DPO_ADJACENCY_MCAST, ai_3,
653 DPO_RECEIVE, 0),
654 "%U replicate OK",
655 format_mfib_prefix, pfx_s_g);
656
657 /*
658 * remove a for-us path
659 */
660 mfib_table_entry_path_remove(fib_index,
661 pfx_s_g,
662 MFIB_SOURCE_API,
663 &path_for_us);
664
665 MFIB_TEST(mfib_test_entry(mfei,
666 MFIB_ENTRY_FLAG_NONE,
667 3,
668 DPO_ADJACENCY_MCAST, ai_1,
669 DPO_ADJACENCY_MCAST, ai_2,
670 DPO_ADJACENCY_MCAST, ai_3),
671 "%U replicate OK",
672 format_mfib_prefix, pfx_s_g);
673
674 /*
675 * update an existing forwarding path to be only accepting
676 * - expect it to be removed from the replication set.
677 */
678 mfib_table_entry_path_update(fib_index,
679 pfx_s_g,
680 MFIB_SOURCE_API,
681 &path_via_if3,
682 MFIB_ITF_FLAG_ACCEPT);
683
684 MFIB_TEST(mfib_test_entry(mfei,
685 MFIB_ENTRY_FLAG_NONE,
686 2,
687 DPO_ADJACENCY_MCAST, ai_1,
688 DPO_ADJACENCY_MCAST, ai_2),
689 "%U replicate OK",
690 format_mfib_prefix, pfx_s_g);
691 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
692 MFIB_ITF_FLAG_ACCEPT));
693 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
694 MFIB_ITF_FLAG_FORWARD));
695 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
696 MFIB_ITF_FLAG_FORWARD));
697 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[3]->sw_if_index,
698 MFIB_ITF_FLAG_ACCEPT));
699 /*
700 * Make the path forwarding again
701 * - expect it to be added back to the replication set
702 */
703 mfib_table_entry_path_update(fib_index,
704 pfx_s_g,
705 MFIB_SOURCE_API,
706 &path_via_if3,
707 (MFIB_ITF_FLAG_FORWARD |
708 MFIB_ITF_FLAG_ACCEPT |
709 MFIB_ITF_FLAG_NEGATE_SIGNAL));
710
711 mfei = mfib_table_lookup_exact_match(fib_index,
712 pfx_s_g);
713
714 MFIB_TEST(mfib_test_entry(mfei,
715 MFIB_ENTRY_FLAG_NONE,
716 3,
717 DPO_ADJACENCY_MCAST, ai_1,
718 DPO_ADJACENCY_MCAST, ai_2,
719 DPO_ADJACENCY_MCAST, ai_3),
720 "%U replicate OK",
721 format_mfib_prefix, pfx_s_g);
722 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
723 MFIB_ITF_FLAG_ACCEPT));
724 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
725 MFIB_ITF_FLAG_FORWARD));
726 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
727 MFIB_ITF_FLAG_FORWARD));
728 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[3]->sw_if_index,
729 (MFIB_ITF_FLAG_FORWARD |
730 MFIB_ITF_FLAG_ACCEPT |
731 MFIB_ITF_FLAG_NEGATE_SIGNAL)));
732
733 /*
734 * update flags on the entry
735 */
736 mfib_table_entry_update(fib_index,
737 pfx_s_g,
738 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800739 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000740 MFIB_ENTRY_FLAG_SIGNAL);
741 MFIB_TEST(mfib_test_entry(mfei,
742 MFIB_ENTRY_FLAG_SIGNAL,
743 3,
744 DPO_ADJACENCY_MCAST, ai_1,
745 DPO_ADJACENCY_MCAST, ai_2,
746 DPO_ADJACENCY_MCAST, ai_3),
747 "%U replicate OK",
748 format_mfib_prefix, pfx_s_g);
749
750 /*
751 * remove paths
752 */
753 mfib_table_entry_path_remove(fib_index,
754 pfx_s_g,
755 MFIB_SOURCE_API,
756 &path_via_if3);
757
758 MFIB_TEST(mfib_test_entry(mfei,
759 MFIB_ENTRY_FLAG_SIGNAL,
760 2,
761 DPO_ADJACENCY_MCAST, ai_1,
762 DPO_ADJACENCY_MCAST, ai_2),
763 "%U replicate OK",
764 format_mfib_prefix, pfx_s_g);
765 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
766 MFIB_ITF_FLAG_ACCEPT));
767 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[1]->sw_if_index,
768 MFIB_ITF_FLAG_FORWARD));
769 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
770 MFIB_ITF_FLAG_FORWARD));
771 MFIB_TEST_NS(mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
772
773 mfib_table_entry_path_remove(fib_index,
774 pfx_s_g,
775 MFIB_SOURCE_API,
776 &path_via_if1);
777
778 MFIB_TEST(mfib_test_entry(mfei,
779 MFIB_ENTRY_FLAG_SIGNAL,
780 1,
781 DPO_ADJACENCY_MCAST, ai_2),
782 "%U replicate OK",
783 format_mfib_prefix, pfx_s_g);
784 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[0]->sw_if_index,
785 MFIB_ITF_FLAG_ACCEPT));
786 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
787 MFIB_ITF_FLAG_FORWARD));
788 MFIB_TEST_NS(mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
789
790 /*
791 * remove the accpeting only interface
792 */
793 mfib_table_entry_path_remove(fib_index,
794 pfx_s_g,
795 MFIB_SOURCE_API,
796 &path_via_if0);
797
798 MFIB_TEST(mfib_test_entry(mfei,
799 MFIB_ENTRY_FLAG_SIGNAL,
800 1,
801 DPO_ADJACENCY_MCAST, ai_2),
802 "%U replicate OK",
803 format_mfib_prefix, pfx_s_g);
804 MFIB_TEST_NS(mfib_test_entry_itf(mfei, tm->hw[2]->sw_if_index,
805 MFIB_ITF_FLAG_FORWARD));
806 MFIB_TEST_NS(mfib_test_entry_no_itf(mfei, tm->hw[0]->sw_if_index));
807 MFIB_TEST_NS(mfib_test_entry_no_itf(mfei, tm->hw[1]->sw_if_index));
808 MFIB_TEST_NS(mfib_test_entry_no_itf(mfei, tm->hw[3]->sw_if_index));
809
810 /*
811 * remove the last path, the entry still has flags so it remains
812 */
813 mfib_table_entry_path_remove(fib_index,
814 pfx_s_g,
815 MFIB_SOURCE_API,
816 &path_via_if2);
817
818 MFIB_TEST(mfib_test_entry(mfei,
819 MFIB_ENTRY_FLAG_SIGNAL,
820 0),
821 "%U no replications",
822 format_mfib_prefix, pfx_s_g);
823
824 /*
825 * update flags on the entry
826 */
827 mfib_table_entry_update(fib_index,
828 pfx_s_g,
829 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800830 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000831 (MFIB_ENTRY_FLAG_SIGNAL |
832 MFIB_ENTRY_FLAG_CONNECTED));
833 MFIB_TEST(mfib_test_entry(mfei,
834 (MFIB_ENTRY_FLAG_SIGNAL |
835 MFIB_ENTRY_FLAG_CONNECTED),
836 0),
837 "%U no replications",
838 format_mfib_prefix, pfx_s_g);
839
840 /*
841 * An entry with a NS interface
842 */
843 mfei_g_2 = mfib_table_entry_path_update(fib_index,
844 pfx_star_g_2,
845 MFIB_SOURCE_API,
846 &path_via_if0,
847 (MFIB_ITF_FLAG_ACCEPT |
848 MFIB_ITF_FLAG_NEGATE_SIGNAL));
849 MFIB_TEST(mfib_test_entry(mfei_g_2,
850 MFIB_ENTRY_FLAG_NONE,
851 0),
852 "%U No replications",
853 format_mfib_prefix, pfx_star_g_2);
854
855 /*
856 * Simulate a signal from the data-plane
857 */
858 {
859 mfib_entry_t *mfe;
860 mfib_itf_t *mfi;
861
862 mfe = mfib_entry_get(mfei_g_2);
863 mfi = mfib_entry_get_itf(mfe, path_via_if0.frp_sw_if_index);
864
865 mfib_signal_push(mfe, mfi, NULL);
866 }
867
868 /*
869 * An entry with a NS interface
870 */
871 mfei_g_3 = mfib_table_entry_path_update(fib_index,
872 pfx_star_g_3,
873 MFIB_SOURCE_API,
874 &path_via_if0,
875 (MFIB_ITF_FLAG_ACCEPT |
876 MFIB_ITF_NEGATE_SIGNAL));
877 MFIB_TEST(mfib_test_entry(mfei_g_3,
878 MFIB_ENTRY_FLAG_NONE,
879 0),
880 "%U No replications",
881 format_mfib_prefix, pfx_star_g_3);
882
883 /*
884 * Simulate a signal from the data-plane
885 */
886 {
887 mfib_entry_t *mfe;
888 mfib_itf_t *mfi;
889
890 mfe = mfib_entry_get(mfei_g_3);
891 mfi = mfib_entry_get_itf(mfe, path_via_if0.frp_sw_if_index);
892
893 mfib_signal_push(mfe, mfi, NULL);
894 }
895
896 if (FIB_PROTOCOL_IP6 == PROTO)
897 {
898 /*
899 * All the entries are present. let's ensure we can find them all
900 * via exact and longest prefix matches.
901 */
902 /*
903 * A source address we will never match
904 */
905 ip6_address_t src = {
906 .as_u64[0] = clib_host_to_net_u64(0x3001000000000000),
907 .as_u64[1] = clib_host_to_net_u64(0xffffffffffffffff),
908 };
909
910 /*
911 * Find the (*,G/m)
912 */
913 MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2(
914 ip6_mfib_get(fib_index),
915 &src,
916 &pfx_star_g_slash_m->fp_grp_addr.ip6)),
917 "%U found via DP LPM grp=%U",
918 format_mfib_prefix, pfx_star_g_slash_m,
919 format_ip6_address, &pfx_star_g_slash_m->fp_grp_addr.ip6);
920
921 ip6_address_t tmp = pfx_star_g_slash_m->fp_grp_addr.ip6;
922 tmp.as_u8[15] = 0xff;
923
924 MFIB_TEST((mfei_g_m == ip6_mfib_table_lookup2(
925 ip6_mfib_get(fib_index),
926 &pfx_s_g->fp_src_addr.ip6,
927 &tmp)),
928 "%U found via DP LPM grp=%U",
929 format_mfib_prefix, pfx_star_g_slash_m,
930 format_ip6_address, &tmp);
931
932 /*
933 * Find the (S,G).
934 */
935 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
936 &pfx_s_g->fp_src_addr.ip6,
937 &pfx_s_g->fp_grp_addr.ip6);
938 MFIB_TEST((mfei_s_g == mfei),
939 "%U found via DP LPM: %d",
940 format_mfib_prefix, pfx_s_g, mfei);
941
942 /*
943 * Find the 3 (*,G) s
944 */
945 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
946 &src,
947 &pfx_star_g_1->fp_grp_addr.ip6);
948 MFIB_TEST((mfei_g_1 == mfei),
949 "%U found via DP LPM: %d",
950 format_mfib_prefix, pfx_star_g_1, mfei);
951 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
952 &src,
953 &pfx_star_g_2->fp_grp_addr.ip6);
954 MFIB_TEST((mfei_g_2 == mfei),
955 "%U found via DP LPM: %d",
956 format_mfib_prefix, pfx_star_g_2, mfei);
957 mfei = ip6_mfib_table_lookup2(ip6_mfib_get(fib_index),
958 &src,
959 &pfx_star_g_3->fp_grp_addr.ip6);
960 MFIB_TEST((mfei_g_3 == mfei),
961 "%U found via DP LPM: %d",
962 format_mfib_prefix, pfx_star_g_3, mfei);
963 }
964
965 /*
966 * remove flags on the entry. This is the last of the
967 * state associated with the entry, so now it goes.
968 */
969 mfib_table_entry_update(fib_index,
970 pfx_s_g,
971 MFIB_SOURCE_API,
Neale Ranns0f26c5a2017-03-01 15:12:11 -0800972 MFIB_RPF_ID_NONE,
Neale Ranns32e1c012016-11-22 17:07:28 +0000973 MFIB_ENTRY_FLAG_NONE);
974 mfei = mfib_table_lookup_exact_match(fib_index,
975 pfx_s_g);
976 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
977 "%U gone",
978 format_mfib_prefix, pfx_s_g);
979
980 /*
981 * remove the last path on the no forward entry - the last entry
982 */
983 mfib_table_entry_path_remove(fib_index,
984 pfx_no_forward,
985 MFIB_SOURCE_API,
986 &path_via_if0);
987
988 mfei = mfib_table_lookup_exact_match(fib_index, pfx_no_forward);
989 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
990 "%U gone",
991 format_mfib_prefix, pfx_no_forward);
992
993 /*
994 * hard delete the (*,232.1.1.1)
995 */
996 mfib_table_entry_delete(fib_index,
997 pfx_star_g_1,
998 MFIB_SOURCE_API);
999
1000 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_1);
1001 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1002 "%U gone",
1003 format_mfib_prefix, pfx_star_g_1);
1004 /*
1005 * remove the entry whilst the signal is pending
1006 */
1007 mfib_table_entry_delete(fib_index,
1008 pfx_star_g_2,
1009 MFIB_SOURCE_API);
1010
1011 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_2);
1012 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1013 "%U Gone",
1014 format_mfib_prefix, pfx_star_g_2);
1015 mfib_table_entry_delete(fib_index,
1016 pfx_star_g_3,
1017 MFIB_SOURCE_API);
1018
1019 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_3);
1020 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1021 "%U Gone",
1022 format_mfib_prefix, pfx_star_g_3);
1023
1024 mfib_table_entry_delete(fib_index,
1025 pfx_star_g_slash_m,
1026 MFIB_SOURCE_API);
1027
1028 mfei = mfib_table_lookup_exact_match(fib_index, pfx_star_g_slash_m);
1029 MFIB_TEST(FIB_NODE_INDEX_INVALID == mfei,
1030 "%U Gone",
1031 format_mfib_prefix, pfx_star_g_slash_m);
1032
1033 /*
Neale Rannsa9374df2017-02-02 02:18:18 -08001034 * Add a prefix as a special/exclusive route
1035 */
1036 dpo_id_t td = DPO_INVALID;
1037 index_t repi = replicate_create(1, fib_proto_to_dpo(PROTO));
1038
1039 dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_2);
1040 replicate_set_bucket(repi, 0, &td);
1041
1042 mfei = mfib_table_entry_special_add(fib_index,
1043 pfx_star_g_3,
1044 MFIB_SOURCE_SRv6,
1045 MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
1046 repi);
1047 MFIB_TEST(mfib_test_entry(mfei,
1048 (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
1049 MFIB_ENTRY_FLAG_EXCLUSIVE),
1050 1,
1051 DPO_ADJACENCY_MCAST, ai_2),
1052 "%U exclusive replicate OK",
1053 format_mfib_prefix, pfx_star_g_3);
1054
1055 /*
1056 * update a special/exclusive route
1057 */
1058 index_t repi2 = replicate_create(1, fib_proto_to_dpo(PROTO));
1059
1060 dpo_set(&td, DPO_ADJACENCY_MCAST, fib_proto_to_dpo(PROTO), ai_1);
1061 replicate_set_bucket(repi2, 0, &td);
1062
1063 mfei = mfib_table_entry_special_add(fib_index,
1064 pfx_star_g_3,
1065 MFIB_SOURCE_SRv6,
1066 MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF,
1067 repi2);
1068 MFIB_TEST(mfib_test_entry(mfei,
1069 (MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF |
1070 MFIB_ENTRY_FLAG_EXCLUSIVE),
1071 1,
1072 DPO_ADJACENCY_MCAST, ai_1),
1073 "%U exclusive update replicate OK",
1074 format_mfib_prefix, pfx_star_g_3);
1075
1076 mfib_table_entry_delete(fib_index,
1077 pfx_star_g_3,
1078 MFIB_SOURCE_SRv6);
1079 dpo_reset(&td);
1080
1081 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001082 * A Multicast LSP. This a mLDP head-end
1083 */
1084 fib_node_index_t ai_mpls_10_10_10_1, lfei;
1085 ip46_address_t nh_10_10_10_1 = {
1086 .ip4 = {
1087 .as_u32 = clib_host_to_net_u32(0x0a0a0a01),
1088 },
1089 };
1090 ai_mpls_10_10_10_1 = adj_nbr_add_or_lock(FIB_PROTOCOL_IP4,
1091 VNET_LINK_MPLS,
1092 &nh_10_10_10_1,
1093 tm->hw[0]->sw_if_index);
1094
1095 fib_prefix_t pfx_3500 = {
1096 .fp_len = 21,
1097 .fp_proto = FIB_PROTOCOL_MPLS,
1098 .fp_label = 3500,
1099 .fp_eos = MPLS_EOS,
1100 .fp_payload_proto = DPO_PROTO_IP4,
1101 };
1102 fib_test_rep_bucket_t mc_0 = {
1103 .type = FT_REP_LABEL_O_ADJ,
1104 .label_o_adj = {
1105 .adj = ai_mpls_10_10_10_1,
1106 .label = 3300,
1107 .eos = MPLS_EOS,
1108 },
1109 };
1110 mpls_label_t *l3300 = NULL;
1111 vec_add1(l3300, 3300);
1112
1113 /*
1114 * MPLS enable an interface so we get the MPLS table created
1115 */
1116 mpls_sw_interface_enable_disable(&mpls_main,
1117 tm->hw[0]->sw_if_index,
1118 1);
1119
1120 lfei = fib_table_entry_update_one_path(0, // default MPLS Table
1121 &pfx_3500,
1122 FIB_SOURCE_API,
1123 FIB_ENTRY_FLAG_MULTICAST,
Neale Rannsda78f952017-05-24 09:15:43 -07001124 DPO_PROTO_IP4,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001125 &nh_10_10_10_1,
1126 tm->hw[0]->sw_if_index,
1127 ~0, // invalid fib index
1128 1,
1129 l3300,
1130 FIB_ROUTE_PATH_FLAG_NONE);
1131 MFIB_TEST(fib_test_validate_entry(lfei,
1132 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
1133 1,
1134 &mc_0),
1135 "3500 via replicate over 10.10.10.1");
1136
1137 /*
1138 * An (S,G) that resolves via the mLDP head-end
1139 */
1140 fib_route_path_t path_via_mldp = {
Neale Rannsda78f952017-05-24 09:15:43 -07001141 .frp_proto = DPO_PROTO_MPLS,
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001142 .frp_local_label = pfx_3500.fp_label,
1143 .frp_eos = MPLS_EOS,
1144 .frp_sw_if_index = 0xffffffff,
1145 .frp_fib_index = 0,
1146 .frp_weight = 1,
1147 .frp_flags = FIB_ROUTE_PATH_FLAG_NONE,
1148 };
1149 dpo_id_t mldp_dpo = DPO_INVALID;
1150
1151 fib_entry_contribute_forwarding(lfei,
1152 FIB_FORW_CHAIN_TYPE_MPLS_EOS,
1153 &mldp_dpo);
1154
1155 mfei = mfib_table_entry_path_update(fib_index,
1156 pfx_s_g,
1157 MFIB_SOURCE_API,
1158 &path_via_mldp,
1159 MFIB_ITF_FLAG_FORWARD);
1160
1161 MFIB_TEST(mfib_test_entry(mfei,
1162 MFIB_ENTRY_FLAG_NONE,
1163 1,
1164 DPO_REPLICATE, mldp_dpo.dpoi_index),
1165 "%U over-mLDP replicate OK",
1166 format_mfib_prefix, pfx_s_g);
1167
1168 /*
1169 * add a for-us path. this tests two types of non-attached paths on one entry
1170 */
1171 mfei = mfib_table_entry_path_update(fib_index,
1172 pfx_s_g,
1173 MFIB_SOURCE_API,
1174 &path_for_us,
1175 MFIB_ITF_FLAG_FORWARD);
1176 MFIB_TEST(mfib_test_entry(mfei,
1177 MFIB_ENTRY_FLAG_NONE,
1178 2,
1179 DPO_REPLICATE, mldp_dpo.dpoi_index,
1180 DPO_RECEIVE, 0),
1181 "%U mLDP+for-us replicate OK",
1182 format_mfib_prefix, pfx_s_g);
1183
1184 mfib_table_entry_delete(fib_index,
1185 pfx_s_g,
1186 MFIB_SOURCE_API);
1187 fib_table_entry_delete(0,
1188 &pfx_3500,
1189 FIB_SOURCE_API);
1190 dpo_reset(&mldp_dpo);
1191
1192 /*
Neale Ranns32e1c012016-11-22 17:07:28 +00001193 * Unlock the table - it's the last lock so should be gone thereafter
1194 */
1195 mfib_table_unlock(fib_index, PROTO);
1196
1197 MFIB_TEST((FIB_NODE_INDEX_INVALID ==
1198 mfib_table_find(PROTO, fib_index)),
1199 "MFIB table %d gone", fib_index);
1200
1201 adj_unlock(ai_1);
1202 adj_unlock(ai_2);
1203 adj_unlock(ai_3);
1204
1205 /*
Neale Ranns0f26c5a2017-03-01 15:12:11 -08001206 * MPLS disable the interface
1207 */
1208 mpls_sw_interface_enable_disable(&mpls_main,
1209 tm->hw[0]->sw_if_index,
1210 0);
1211
1212 /*
Neale Ranns32e1c012016-11-22 17:07:28 +00001213 * test we've leaked no resources
1214 */
1215 MFIB_TEST(0 == adj_mcast_db_size(), "%d MCAST adjs", adj_mcast_db_size());
Neale Rannsa9374df2017-02-02 02:18:18 -08001216 MFIB_TEST(n_pls == fib_path_list_pool_size(), "%d=%d path-lists",
1217 n_pls, fib_path_list_pool_size());
Neale Ranns32e1c012016-11-22 17:07:28 +00001218 MFIB_TEST(n_reps == pool_elts(replicate_pool), "%d=%d replicates",
1219 n_reps, pool_elts(replicate_pool));
1220 MFIB_TEST(n_entries == pool_elts(mfib_entry_pool),
1221 " No more entries %d!=%d",
1222 n_entries, pool_elts(mfib_entry_pool));
1223 MFIB_TEST(n_itfs == pool_elts(mfib_itf_pool),
1224 " No more Interfaces %d!=%d",
1225 n_itfs, pool_elts(mfib_itf_pool));
1226
1227 return (0);
1228}
1229
1230static int
1231mfib_test_v4 (void)
1232{
1233 const mfib_prefix_t pfx_224_s_8 = {
1234 .fp_len = 8,
1235 .fp_proto = FIB_PROTOCOL_IP4,
1236 .fp_grp_addr = {
1237 .ip4.as_u32 = clib_host_to_net_u32(0xe0000000),
1238 }
1239 };
1240 const mfib_prefix_t pfx_1_1_1_1_c_239_1_1_1 = {
1241 .fp_len = 64,
1242 .fp_proto = FIB_PROTOCOL_IP4,
1243 .fp_grp_addr = {
1244 .ip4.as_u32 = clib_host_to_net_u32(0xef010101),
1245 },
1246 .fp_src_addr = {
1247 .ip4.as_u32 = clib_host_to_net_u32(0x01010101),
1248 },
1249 };
1250 const mfib_prefix_t pfx_239_1_1_1 = {
1251 .fp_len = 32,
1252 .fp_proto = FIB_PROTOCOL_IP4,
1253 .fp_grp_addr = {
1254 .ip4.as_u32 = clib_host_to_net_u32(0xef010101),
1255 },
1256 .fp_src_addr = {
1257 .ip4.as_u32 = 0,
1258 },
1259 };
1260 const mfib_prefix_t pfx_239_1_1_2 = {
1261 .fp_len = 32,
1262 .fp_proto = FIB_PROTOCOL_IP4,
1263 .fp_grp_addr = {
1264 .ip4.as_u32 = clib_host_to_net_u32(0xef010102),
1265 },
1266 .fp_src_addr = {
1267 .ip4.as_u32 = 0,
1268 },
1269 };
1270 const mfib_prefix_t pfx_239_1_1_3 = {
1271 .fp_len = 32,
1272 .fp_proto = FIB_PROTOCOL_IP4,
1273 .fp_grp_addr = {
1274 .ip4.as_u32 = clib_host_to_net_u32(0xef010103),
1275 },
1276 .fp_src_addr = {
1277 .ip4.as_u32 = 0,
1278 },
1279 };
1280 const mfib_prefix_t pfx_239 = {
1281 .fp_len = 8,
1282 .fp_proto = FIB_PROTOCOL_IP4,
1283 .fp_grp_addr = {
1284 .ip4.as_u32 = clib_host_to_net_u32(0xef000000),
1285 },
1286 .fp_src_addr = {
1287 .ip4.as_u32 = 0,
1288 },
1289 };
1290
1291 return (mfib_test_i(FIB_PROTOCOL_IP4,
1292 VNET_LINK_IP4,
1293 &pfx_224_s_8,
1294 &pfx_1_1_1_1_c_239_1_1_1,
1295 &pfx_239_1_1_1,
1296 &pfx_239_1_1_2,
1297 &pfx_239_1_1_3,
1298 &pfx_239));
1299}
1300
1301static int
1302mfib_test_v6 (void)
1303{
1304 const mfib_prefix_t pfx_ffd_s_12 = {
1305 .fp_len = 12,
1306 .fp_proto = FIB_PROTOCOL_IP6,
1307 .fp_grp_addr = {
1308 .ip6.as_u64[0] = clib_host_to_net_u64(0xffd0000000000000),
1309 }
1310 };
1311 const mfib_prefix_t pfx_2001_1_c_ff_1 = {
1312 .fp_len = 256,
1313 .fp_proto = FIB_PROTOCOL_IP6,
1314 .fp_grp_addr = {
1315 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1316 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1317 },
1318 .fp_src_addr = {
1319 .ip6.as_u64[0] = clib_host_to_net_u64(0x2001000000000000),
1320 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1321 },
1322 };
1323 const mfib_prefix_t pfx_ff_1 = {
1324 .fp_len = 128,
1325 .fp_proto = FIB_PROTOCOL_IP6,
1326 .fp_grp_addr = {
1327 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1328 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000001),
1329 },
1330 };
1331 const mfib_prefix_t pfx_ff_2 = {
1332 .fp_len = 128,
1333 .fp_proto = FIB_PROTOCOL_IP6,
1334 .fp_grp_addr = {
1335 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1336 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000002),
1337 },
1338 };
1339 const mfib_prefix_t pfx_ff_3 = {
1340 /*
1341 * this is the ALL DHCP routers address
1342 */
1343 .fp_len = 128,
1344 .fp_proto = FIB_PROTOCOL_IP6,
1345 .fp_grp_addr = {
1346 .ip6.as_u64[0] = clib_host_to_net_u64(0xff02000100000000),
1347 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000002),
1348 },
1349 };
1350 const mfib_prefix_t pfx_ff = {
1351 .fp_len = 16,
1352 .fp_proto = FIB_PROTOCOL_IP6,
1353 .fp_grp_addr = {
1354 .ip6.as_u64[0] = clib_host_to_net_u64(0xff01000000000000),
1355 .ip6.as_u64[1] = clib_host_to_net_u64(0x0000000000000000),
1356 },
1357 };
1358
1359 return (mfib_test_i(FIB_PROTOCOL_IP6,
1360 VNET_LINK_IP6,
1361 &pfx_ffd_s_12,
1362 &pfx_2001_1_c_ff_1,
1363 &pfx_ff_1,
1364 &pfx_ff_2,
1365 &pfx_ff_3,
1366 &pfx_ff));
1367}
1368
1369static clib_error_t *
1370mfib_test (vlib_main_t * vm,
1371 unformat_input_t * input,
1372 vlib_cli_command_t * cmd_arg)
1373{
1374 int res = 0;
1375
1376 res += mfib_test_mk_intf(4);
1377 res += mfib_test_v4();
1378 res += mfib_test_v6();
1379
1380 if (res)
1381 {
1382 return clib_error_return(0, "MFIB Unit Test Failed");
1383 }
1384 else
1385 {
1386 return (NULL);
1387 }
1388}
1389
1390VLIB_CLI_COMMAND (test_fib_command, static) = {
1391 .path = "test mfib",
Neale Rannsa9374df2017-02-02 02:18:18 -08001392 .short_help = "mfib unit tests - DO NOT RUN ON A LIVE SYSTEM",
Neale Ranns32e1c012016-11-22 17:07:28 +00001393 .function = mfib_test,
1394};
1395
1396clib_error_t *
1397mfib_test_init (vlib_main_t *vm)
1398{
1399 return 0;
1400}
1401
1402VLIB_INIT_FUNCTION (mfib_test_init);