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