1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * BGP Peer Attribute Unit Tests
4 * Copyright (C) 2018 Pascal Mathis
11 #include "bgpd/bgpd.h"
12 #include "bgpd/bgp_attr.h"
13 #include "bgpd/bgp_regex.h"
14 #include "bgpd/bgp_clist.h"
15 #include "bgpd/bgp_dump.h"
16 #include "bgpd/bgp_filter.h"
17 #include "bgpd/bgp_route.h"
18 #include "bgpd/bgp_vty.h"
19 #include "bgpd/bgp_zebra.h"
20 #include "bgpd/bgp_network.h"
23 #include "bgpd/rfapi/rfapi_backend.h"
26 #define OUT_SYMBOL_INFO "\u25ba"
27 #define OUT_SYMBOL_OK "\u2714"
28 #define OUT_SYMBOL_NOK "\u2716"
30 #define TEST_ASSERT(T, C) \
32 if ((T)->state != TEST_SUCCESS || (C)) \
34 (T)->state = TEST_ASSERT_ERROR; \
36 asprintfrr(MTYPE_TMP, "assertion failed: %s (%s:%d)", \
37 (#C), __FILE__, __LINE__); \
40 #define TEST_ASSERT_EQ(T, A, B) \
42 if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
44 (T)->state = TEST_ASSERT_ERROR; \
45 (T)->error = asprintfrr( \
47 "assertion failed: %s[%lld] == [%lld]%s (%s:%d)", \
48 (#A), (long long)(A), (long long)(B), (#B), __FILE__, \
52 #define TEST_HANDLER_MAX 5
53 #define TEST_HANDLER(name) _test_handler_##name
54 #define TEST_HANDLER_DECL(name) \
55 static void _test_handler_##name( \
56 struct test *test, struct test_peer_attr *pa, \
57 struct peer *peer, struct peer *group, bool peer_set, \
60 #define TEST_ATTR_HANDLER_DECL(name, attr, pval, gval) \
61 TEST_HANDLER_DECL(name) \
64 TEST_ASSERT_EQ(test, peer->attr, (pval)); \
65 else if (peer_group_active(peer) && group_set) \
66 TEST_ASSERT_EQ(test, peer->attr, (gval)); \
68 TEST_ASSERT_EQ(test, group->attr, (gval)); \
70 TEST_HANDLER_DECL(name)
72 #define TEST_STR_ATTR_HANDLER_DECL(name, attr, pval, gval) \
73 TEST_HANDLER_DECL(name) \
76 TEST_ASSERT(test, peer->attr != NULL); \
77 TEST_ASSERT(test, !strcmp(peer->attr, (pval))); \
78 } else if (peer_group_active(peer) && group_set) { \
79 TEST_ASSERT(test, peer->attr != NULL); \
80 TEST_ASSERT(test, !strcmp(peer->attr, (gval))); \
83 TEST_ASSERT(test, group->attr != NULL); \
84 TEST_ASSERT(test, !strcmp(group->attr, (gval))); \
87 TEST_HANDLER_DECL(name)
89 #define TEST_SU_ATTR_HANDLER_DECL(name, attr, pval, gval) \
90 TEST_HANDLER_DECL(name) \
94 str2sockunion(pval, &su); \
95 TEST_ASSERT(test, !sockunion_cmp(peer->attr, &su)); \
96 } else if (peer_group_active(peer) && group_set) { \
97 str2sockunion(gval, &su); \
98 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
101 str2sockunion(gval, &su); \
102 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
105 TEST_HANDLER_DECL(name)
107 /* Required variables to link in libbgp */
108 struct zebra_privs_t bgpd_privs
= {0};
109 struct event_loop
*master
;
121 enum test_peer_attr_type
{
123 PEER_AT_AF_FILTER
= 1,
124 PEER_AT_AF_CUSTOM
= 2,
125 PEER_AT_GLOBAL_FLAG
= 3,
126 PEER_AT_GLOBAL_CUSTOM
= 4
130 enum test_state state
;
138 struct peer_group
*group
;
149 const char *peer_address
;
150 const char *peer_interface
;
151 const char *peer_group
;
154 struct test_peer_family
{
159 struct test_peer_attr
{
161 const char *peer_cmd
;
162 const char *group_cmd
;
164 enum test_peer_attr_type type
;
177 bool skip_xfer_cases
;
182 struct test_peer_family families
[AFI_MAX
* SAFI_MAX
];
184 void (*handlers
[TEST_HANDLER_MAX
])(struct test
*test
,
185 struct test_peer_attr
*pa
,
187 struct peer
*group
, bool peer_set
,
191 static struct test_config cfg
= {
194 .peer_address
= "1.1.1.1",
195 .peer_interface
= "IP-TEST",
196 .peer_group
= "PG-TEST",
199 static struct test_peer_family test_default_families
[] = {
200 {.afi
= AFI_IP
, .safi
= SAFI_UNICAST
},
201 {.afi
= AFI_IP
, .safi
= SAFI_MULTICAST
},
202 {.afi
= AFI_IP6
, .safi
= SAFI_UNICAST
},
203 {.afi
= AFI_IP6
, .safi
= SAFI_MULTICAST
},
206 TEST_ATTR_HANDLER_DECL(advertisement_interval
, v_routeadv
, 10, 20);
207 TEST_STR_ATTR_HANDLER_DECL(password
, password
, "FRR-Peer", "FRR-Group");
208 TEST_ATTR_HANDLER_DECL(local_as
, change_local_as
, 1, 2);
209 TEST_ATTR_HANDLER_DECL(timers_1
, keepalive
, 10, 20);
210 TEST_ATTR_HANDLER_DECL(timers_2
, holdtime
, 30, 60);
211 TEST_ATTR_HANDLER_DECL(addpath_types
, addpath_type
[pa
->afi
][pa
->safi
],
212 BGP_ADDPATH_ALL
, BGP_ADDPATH_BEST_PER_AS
);
213 TEST_SU_ATTR_HANDLER_DECL(update_source_su
, update_source
, "255.255.255.1",
215 TEST_STR_ATTR_HANDLER_DECL(update_source_if
, update_if
, "IF-PEER", "IF-GROUP");
217 TEST_ATTR_HANDLER_DECL(allowas_in
, allowas_in
[pa
->afi
][pa
->safi
], 1, 2);
218 TEST_STR_ATTR_HANDLER_DECL(default_originate_route_map
,
219 default_rmap
[pa
->afi
][pa
->safi
].name
, "RM-PEER",
221 TEST_STR_ATTR_HANDLER_DECL(
223 filter
[pa
->afi
][pa
->safi
].dlist
[pa
->u
.filter
.direct
].name
, "DL-PEER",
225 TEST_STR_ATTR_HANDLER_DECL(
226 filter_list
, filter
[pa
->afi
][pa
->safi
].aslist
[pa
->u
.filter
.direct
].name
,
227 "FL-PEER", "FL-GROUP");
228 TEST_ATTR_HANDLER_DECL(maximum_prefix
, pmax
[pa
->afi
][pa
->safi
], 10, 20);
229 TEST_ATTR_HANDLER_DECL(maximum_prefix_threshold
,
230 pmax_threshold
[pa
->afi
][pa
->safi
], 1, 2);
231 TEST_ATTR_HANDLER_DECL(maximum_prefix_restart
, pmax_restart
[pa
->afi
][pa
->safi
],
233 TEST_STR_ATTR_HANDLER_DECL(
234 prefix_list
, filter
[pa
->afi
][pa
->safi
].plist
[pa
->u
.filter
.direct
].name
,
235 "PL-PEER", "PL-GROUP");
236 TEST_STR_ATTR_HANDLER_DECL(
237 route_map
, filter
[pa
->afi
][pa
->safi
].map
[pa
->u
.filter
.direct
].name
,
238 "RM-PEER", "RM-GROUP");
239 TEST_STR_ATTR_HANDLER_DECL(unsuppress_map
, filter
[pa
->afi
][pa
->safi
].usmap
.name
,
240 "UM-PEER", "UM-GROUP");
241 TEST_ATTR_HANDLER_DECL(weight
, weight
[pa
->afi
][pa
->safi
], 100, 200);
243 /* clang-format off */
244 static struct test_peer_attr test_peer_attrs
[] = {
245 /* Peer Attributes */
247 .cmd
= "advertisement-interval",
248 .peer_cmd
= "advertisement-interval 10",
249 .group_cmd
= "advertisement-interval 20",
250 .u
.flag
= PEER_FLAG_ROUTEADV
,
251 .type
= PEER_AT_GLOBAL_FLAG
,
252 .handlers
[0] = TEST_HANDLER(advertisement_interval
),
255 .cmd
= "capability dynamic",
256 .u
.flag
= PEER_FLAG_DYNAMIC_CAPABILITY
,
257 .type
= PEER_AT_GLOBAL_FLAG
,
260 .cmd
= "capability extended-nexthop",
261 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
262 .type
= PEER_AT_GLOBAL_FLAG
,
265 .cmd
= "capability extended-nexthop",
266 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
267 .type
= PEER_AT_GLOBAL_FLAG
,
268 .o
.invert_peer
= true,
269 .o
.use_iface_peer
= true,
272 .cmd
= "capability software-version",
273 .u
.flag
= PEER_FLAG_CAPABILITY_SOFT_VERSION
,
274 .type
= PEER_AT_GLOBAL_FLAG
,
277 .cmd
= "capability software-version",
278 .u
.flag
= PEER_FLAG_CAPABILITY_SOFT_VERSION
,
279 .type
= PEER_AT_GLOBAL_FLAG
,
280 .o
.invert_peer
= true,
281 .o
.use_iface_peer
= true,
284 .cmd
= "description",
285 .peer_cmd
= "description FRR Peer",
286 .group_cmd
= "description FRR Group",
287 .type
= PEER_AT_GLOBAL_CUSTOM
,
290 .cmd
= "disable-connected-check",
291 .u
.flag
= PEER_FLAG_DISABLE_CONNECTED_CHECK
,
292 .type
= PEER_AT_GLOBAL_FLAG
,
295 .cmd
= "dont-capability-negotiate",
296 .u
.flag
= PEER_FLAG_DONT_CAPABILITY
,
297 .type
= PEER_AT_GLOBAL_FLAG
,
300 .cmd
= "enforce-first-as",
301 .u
.flag
= PEER_FLAG_ENFORCE_FIRST_AS
,
302 .type
= PEER_AT_GLOBAL_FLAG
,
306 .peer_cmd
= "local-as 1",
307 .group_cmd
= "local-as 2",
308 .u
.flag
= PEER_FLAG_LOCAL_AS
,
309 .type
= PEER_AT_GLOBAL_FLAG
,
310 .handlers
[0] = TEST_HANDLER(local_as
),
313 .cmd
= "local-as 1 no-prepend",
314 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_NO_PREPEND
,
315 .type
= PEER_AT_GLOBAL_FLAG
,
318 .cmd
= "local-as 1 no-prepend replace-as",
319 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_REPLACE_AS
,
320 .type
= PEER_AT_GLOBAL_FLAG
,
323 .cmd
= "override-capability",
324 .u
.flag
= PEER_FLAG_OVERRIDE_CAPABILITY
,
325 .type
= PEER_AT_GLOBAL_FLAG
,
329 .u
.flag
= PEER_FLAG_PASSIVE
,
330 .type
= PEER_AT_GLOBAL_FLAG
,
334 .peer_cmd
= "password FRR-Peer",
335 .group_cmd
= "password FRR-Group",
336 .u
.flag
= PEER_FLAG_PASSWORD
,
337 .type
= PEER_AT_GLOBAL_FLAG
,
338 .handlers
[0] = TEST_HANDLER(password
),
342 .u
.flag
= PEER_FLAG_SHUTDOWN
,
343 .type
= PEER_AT_GLOBAL_FLAG
,
346 .cmd
= "strict-capability-match",
347 .u
.flag
= PEER_FLAG_STRICT_CAP_MATCH
,
348 .type
= PEER_AT_GLOBAL_FLAG
,
352 .peer_cmd
= "timers 10 30",
353 .group_cmd
= "timers 20 60",
354 .u
.flag
= PEER_FLAG_TIMER
,
355 .type
= PEER_AT_GLOBAL_FLAG
,
356 .handlers
[0] = TEST_HANDLER(timers_1
),
357 .handlers
[1] = TEST_HANDLER(timers_2
),
360 .cmd
= "timers connect",
361 .peer_cmd
= "timers connect 10",
362 .group_cmd
= "timers connect 20",
363 .u
.flag
= PEER_FLAG_TIMER_CONNECT
,
364 .type
= PEER_AT_GLOBAL_FLAG
,
367 .cmd
= "update-source",
368 .peer_cmd
= "update-source 255.255.255.1",
369 .group_cmd
= "update-source 255.255.255.2",
370 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
371 .type
= PEER_AT_GLOBAL_FLAG
,
372 .handlers
[0] = TEST_HANDLER(update_source_su
),
375 .cmd
= "update-source",
376 .peer_cmd
= "update-source IF-PEER",
377 .group_cmd
= "update-source IF-GROUP",
378 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
379 .type
= PEER_AT_GLOBAL_FLAG
,
380 .handlers
[0] = TEST_HANDLER(update_source_if
),
383 /* Address Family Attributes */
386 .peer_cmd
= "addpath-tx-all-paths",
387 .group_cmd
= "addpath-tx-bestpath-per-AS",
388 .type
= PEER_AT_AF_CUSTOM
,
389 .handlers
[0] = TEST_HANDLER(addpath_types
),
393 .peer_cmd
= "allowas-in 1",
394 .group_cmd
= "allowas-in 2",
395 .u
.flag
= PEER_FLAG_ALLOWAS_IN
,
396 .handlers
[0] = TEST_HANDLER(allowas_in
),
399 .cmd
= "allowas-in origin",
400 .u
.flag
= PEER_FLAG_ALLOWAS_IN_ORIGIN
,
403 .cmd
= "as-override",
404 .u
.flag
= PEER_FLAG_AS_OVERRIDE
,
407 .cmd
= "attribute-unchanged as-path",
408 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
,
411 .cmd
= "attribute-unchanged next-hop",
412 .u
.flag
= PEER_FLAG_NEXTHOP_UNCHANGED
,
415 .cmd
= "attribute-unchanged med",
416 .u
.flag
= PEER_FLAG_MED_UNCHANGED
,
419 .cmd
= "attribute-unchanged as-path next-hop",
420 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
421 | PEER_FLAG_NEXTHOP_UNCHANGED
,
424 .cmd
= "attribute-unchanged as-path med",
425 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
426 | PEER_FLAG_MED_UNCHANGED
,
429 .cmd
= "attribute-unchanged as-path next-hop med",
430 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
431 | PEER_FLAG_NEXTHOP_UNCHANGED
432 | PEER_FLAG_MED_UNCHANGED
,
435 .cmd
= "capability orf prefix-list send",
436 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
,
439 .cmd
= "capability orf prefix-list receive",
440 .u
.flag
= PEER_FLAG_ORF_PREFIX_RM
,
443 .cmd
= "capability orf prefix-list both",
444 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
| PEER_FLAG_ORF_PREFIX_RM
,
447 .cmd
= "default-originate",
448 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
451 .cmd
= "default-originate route-map",
452 .peer_cmd
= "default-originate route-map RM-PEER",
453 .group_cmd
= "default-originate route-map RM-GROUP",
454 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
455 .handlers
[0] = TEST_HANDLER(default_originate_route_map
),
458 .cmd
= "distribute-list",
459 .peer_cmd
= "distribute-list DL-PEER in",
460 .group_cmd
= "distribute-list DL-GROUP in",
461 .type
= PEER_AT_AF_FILTER
,
462 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
463 .u
.filter
.direct
= FILTER_IN
,
464 .handlers
[0] = TEST_HANDLER(distribute_list
),
467 .cmd
= "distribute-list",
468 .peer_cmd
= "distribute-list DL-PEER out",
469 .group_cmd
= "distribute-list DL-GROUP out",
470 .type
= PEER_AT_AF_FILTER
,
471 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
472 .u
.filter
.direct
= FILTER_OUT
,
473 .handlers
[0] = TEST_HANDLER(distribute_list
),
476 .cmd
= "filter-list",
477 .peer_cmd
= "filter-list FL-PEER in",
478 .group_cmd
= "filter-list FL-GROUP in",
479 .type
= PEER_AT_AF_FILTER
,
480 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
481 .u
.filter
.direct
= FILTER_IN
,
482 .handlers
[0] = TEST_HANDLER(filter_list
),
485 .cmd
= "filter-list",
486 .peer_cmd
= "filter-list FL-PEER out",
487 .group_cmd
= "filter-list FL-GROUP out",
488 .type
= PEER_AT_AF_FILTER
,
489 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
490 .u
.filter
.direct
= FILTER_OUT
,
491 .handlers
[0] = TEST_HANDLER(filter_list
),
494 .cmd
= "maximum-prefix",
495 .peer_cmd
= "maximum-prefix 10",
496 .group_cmd
= "maximum-prefix 20",
497 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
498 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
501 .cmd
= "maximum-prefix",
502 .peer_cmd
= "maximum-prefix 10 restart 100",
503 .group_cmd
= "maximum-prefix 20 restart 200",
504 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
505 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
506 .handlers
[1] = TEST_HANDLER(maximum_prefix_restart
),
509 .cmd
= "maximum-prefix",
510 .peer_cmd
= "maximum-prefix 10 1 restart 100",
511 .group_cmd
= "maximum-prefix 20 2 restart 200",
512 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
513 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
514 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
515 .handlers
[2] = TEST_HANDLER(maximum_prefix_restart
),
518 .cmd
= "maximum-prefix",
519 .peer_cmd
= "maximum-prefix 10 warning-only",
520 .group_cmd
= "maximum-prefix 20 warning-only",
521 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
522 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
525 .cmd
= "maximum-prefix",
526 .peer_cmd
= "maximum-prefix 10 1 warning-only",
527 .group_cmd
= "maximum-prefix 20 2 warning-only",
528 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
529 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
530 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
533 .cmd
= "next-hop-self",
534 .u
.flag
= PEER_FLAG_NEXTHOP_SELF
,
537 .cmd
= "next-hop-self force",
538 .u
.flag
= PEER_FLAG_FORCE_NEXTHOP_SELF
,
541 .cmd
= "prefix-list",
542 .peer_cmd
= "prefix-list PL-PEER in",
543 .group_cmd
= "prefix-list PL-GROUP in",
544 .type
= PEER_AT_AF_FILTER
,
545 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
546 .u
.filter
.direct
= FILTER_IN
,
547 .handlers
[0] = TEST_HANDLER(prefix_list
),
550 .cmd
= "prefix-list",
551 .peer_cmd
= "prefix-list PL-PEER out",
552 .group_cmd
= "prefix-list PL-GROUP out",
553 .type
= PEER_AT_AF_FILTER
,
554 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
555 .u
.filter
.direct
= FILTER_OUT
,
556 .handlers
[0] = TEST_HANDLER(prefix_list
),
559 .cmd
= "remove-private-AS",
560 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
,
563 .cmd
= "remove-private-AS all",
564 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
565 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL
,
568 .cmd
= "remove-private-AS replace-AS",
569 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
570 | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
,
573 .cmd
= "remove-private-AS all replace-AS",
574 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
,
578 .peer_cmd
= "route-map RM-PEER in",
579 .group_cmd
= "route-map RM-GROUP in",
580 .type
= PEER_AT_AF_FILTER
,
581 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
582 .u
.filter
.direct
= FILTER_IN
,
583 .handlers
[0] = TEST_HANDLER(route_map
),
587 .peer_cmd
= "route-map RM-PEER out",
588 .group_cmd
= "route-map RM-GROUP out",
589 .type
= PEER_AT_AF_FILTER
,
590 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
591 .u
.filter
.direct
= FILTER_OUT
,
592 .handlers
[0] = TEST_HANDLER(route_map
),
595 .cmd
= "route-reflector-client",
596 .u
.flag
= PEER_FLAG_REFLECTOR_CLIENT
,
598 .o
.skip_xfer_cases
= true,
601 .cmd
= "route-server-client",
602 .u
.flag
= PEER_FLAG_RSERVER_CLIENT
,
605 .cmd
= "send-community",
606 .u
.flag
= PEER_FLAG_SEND_COMMUNITY
,
607 .o
.invert_peer
= true,
608 .o
.invert_group
= true,
611 .cmd
= "send-community extended",
612 .u
.flag
= PEER_FLAG_SEND_EXT_COMMUNITY
,
613 .o
.invert_peer
= true,
614 .o
.invert_group
= true,
617 .cmd
= "send-community large",
618 .u
.flag
= PEER_FLAG_SEND_LARGE_COMMUNITY
,
619 .o
.invert_peer
= true,
620 .o
.invert_group
= true,
623 .cmd
= "soft-reconfiguration inbound",
624 .u
.flag
= PEER_FLAG_SOFT_RECONFIG
,
627 .cmd
= "unsuppress-map",
628 .peer_cmd
= "unsuppress-map UM-PEER",
629 .group_cmd
= "unsuppress-map UM-GROUP",
630 .type
= PEER_AT_AF_FILTER
,
631 .u
.filter
.flag
= PEER_FT_UNSUPPRESS_MAP
,
632 .u
.filter
.direct
= 0,
633 .handlers
[0] = TEST_HANDLER(unsuppress_map
),
637 .peer_cmd
= "weight 100",
638 .group_cmd
= "weight 200",
639 .u
.flag
= PEER_FLAG_WEIGHT
,
640 .handlers
[0] = TEST_HANDLER(weight
),
644 .peer_cmd
= "accept-own",
645 .group_cmd
= "accept-own",
646 .families
[0] = {.afi
= AFI_IP
, .safi
= SAFI_MPLS_VPN
},
647 .families
[1] = {.afi
= AFI_IP6
, .safi
= SAFI_MPLS_VPN
},
648 .u
.flag
= PEER_FLAG_ACCEPT_OWN
,
652 /* clang-format on */
654 static const char *str_from_afi(afi_t afi
)
668 assert(!"Reached end of function we should never reach");
671 static const char *str_from_attr_type(enum test_peer_attr_type at
)
674 case PEER_AT_GLOBAL_FLAG
:
676 case PEER_AT_AF_FLAG
:
678 case PEER_AT_AF_FILTER
:
680 case PEER_AT_GLOBAL_CUSTOM
:
681 case PEER_AT_AF_CUSTOM
:
688 static bool is_attr_type_global(enum test_peer_attr_type at
)
690 return at
== PEER_AT_GLOBAL_FLAG
|| at
== PEER_AT_GLOBAL_CUSTOM
;
694 static void test_log(struct test
*test
, const char *fmt
, ...)
698 /* Skip logging if test instance has previously failed. */
699 if (test
->state
!= TEST_SUCCESS
)
702 /* Store formatted log message. */
704 listnode_add(test
->log
, vasprintfrr(MTYPE_TMP
, fmt
, ap
));
709 static void test_execute(struct test
*test
, const char *fmt
, ...)
716 /* Skip execution if test instance has previously failed. */
717 if (test
->state
!= TEST_SUCCESS
)
720 /* Format command string with variadic arguments. */
722 cmd
= vasprintfrr(MTYPE_TMP
, fmt
, ap
);
725 test
->state
= TEST_INTERNAL_ERROR
;
726 test
->error
= asprintfrr(
727 MTYPE_TMP
, "could not format command string [%s]", fmt
);
731 /* Tokenize formatted command string. */
732 vline
= cmd_make_strvec(cmd
);
734 test
->state
= TEST_INTERNAL_ERROR
;
735 test
->error
= asprintfrr(
737 "tokenizing command string [%s] returned empty result",
739 XFREE(MTYPE_TMP
, cmd
);
744 /* Execute command (non-strict). */
745 ret
= cmd_execute_command(vline
, test
->vty
, NULL
, 0);
746 if (ret
!= CMD_SUCCESS
) {
747 test
->state
= TEST_COMMAND_ERROR
;
748 test
->error
= asprintfrr(
750 "execution of command [%s] has failed with code [%d]",
755 cmd_free_strvec(vline
);
756 XFREE(MTYPE_TMP
, cmd
);
760 static void test_config(struct test
*test
, const char *fmt
, bool invert
,
768 /* Skip execution if test instance has previously failed. */
769 if (test
->state
!= TEST_SUCCESS
)
772 /* Format matcher string with variadic arguments. */
774 matcher
= vasprintfrr(MTYPE_TMP
, fmt
, apc
);
777 test
->state
= TEST_INTERNAL_ERROR
;
778 test
->error
= asprintfrr(
779 MTYPE_TMP
, "could not format matcher string [%s]", fmt
);
783 /* Fetch BGP configuration into buffer. */
784 bgp_config_write(test
->vty
);
785 config
= buffer_getstr(test
->vty
->obuf
);
786 buffer_reset(test
->vty
->obuf
);
788 /* Match config against matcher. */
789 matched
= !!strstr(config
, matcher
);
790 if (!matched
&& !invert
) {
791 test
->state
= TEST_CONFIG_ERROR
;
792 test
->error
= asprintfrr(MTYPE_TMP
,
793 "expected config [%s] to be present",
795 } else if (matched
&& invert
) {
796 test
->state
= TEST_CONFIG_ERROR
;
797 test
->error
= asprintfrr(MTYPE_TMP
,
798 "expected config [%s] to be absent",
802 /* Free memory and return. */
803 XFREE(MTYPE_TMP
, matcher
);
804 XFREE(MTYPE_TMP
, config
);
808 static void test_config_present(struct test
*test
, const char *fmt
, ...)
813 test_config(test
, fmt
, false, ap
);
818 static void test_config_absent(struct test
*test
, const char *fmt
, ...)
823 test_config(test
, fmt
, true, ap
);
827 static void test_initialize(struct test
*test
)
831 /* Skip execution if test instance has previously failed. */
832 if (test
->state
!= TEST_SUCCESS
)
835 /* Log message about (re)-initialization */
836 test_log(test
, "prepare: %sinitialize bgp test environment",
837 test
->bgp
? "re-" : "");
839 /* Attempt gracefully to purge previous BGP configuration. */
840 test_execute(test
, "no router bgp");
841 test
->state
= TEST_SUCCESS
;
843 /* Initialize BGP test environment. */
844 test_execute(test
, "router bgp %d", cfg
.local_asn
);
845 test_execute(test
, "no bgp default ipv4-unicast");
846 test_execute(test
, "neighbor %s peer-group", cfg
.peer_group
);
847 if (test
->o
.use_iface_peer
) {
848 test_execute(test
, "neighbor %s interface", cfg
.peer_interface
);
849 test_execute(test
, "neighbor %s remote-as %d",
851 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
853 test_execute(test
, "neighbor %s remote-as %d", cfg
.peer_address
,
854 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
857 if (test
->state
!= TEST_SUCCESS
)
860 /* Fetch default BGP instance. */
861 test
->bgp
= bgp_get_default();
863 test
->state
= TEST_INTERNAL_ERROR
;
864 test
->error
= asprintfrr(
865 MTYPE_TMP
, "could not retrieve default bgp instance");
869 /* Fetch peer instance. */
870 if (test
->o
.use_iface_peer
) {
872 peer_lookup_by_conf_if(test
->bgp
, cfg
.peer_interface
);
874 str2sockunion(cfg
.peer_address
, &su
);
875 test
->peer
= peer_lookup(test
->bgp
, &su
);
878 test
->state
= TEST_INTERNAL_ERROR
;
879 test
->error
= asprintfrr(
881 "could not retrieve instance of bgp peer [%s]",
886 /* Fetch peer-group instance. */
887 test
->group
= peer_group_lookup(test
->bgp
, cfg
.peer_group
);
889 test
->state
= TEST_INTERNAL_ERROR
;
890 test
->error
= asprintfrr(
892 "could not retrieve instance of bgp peer-group [%s]",
898 static struct test
*test_new(const char *desc
, bool use_ibgp
,
903 test
= XCALLOC(MTYPE_TMP
, sizeof(struct test
));
904 test
->state
= TEST_SUCCESS
;
905 test
->desc
= XSTRDUP(MTYPE_TMP
, desc
);
906 test
->log
= list_new();
907 test
->o
.use_ibgp
= use_ibgp
;
908 test
->o
.use_iface_peer
= use_iface_peer
;
910 test
->vty
= vty_new();
911 test
->vty
->type
= VTY_TERM
;
912 test
->vty
->node
= CONFIG_NODE
;
914 test_initialize(test
);
919 static void test_finish(struct test
*test
)
922 struct listnode
*node
, *nnode
;
924 /* Print test output header. */
925 printf("%s [test] %s\n",
926 (test
->state
== TEST_SUCCESS
) ? OUT_SYMBOL_OK
: OUT_SYMBOL_NOK
,
929 /* Print test log messages. */
930 for (ALL_LIST_ELEMENTS(test
->log
, node
, nnode
, msg
)) {
931 printf("%s %s\n", OUT_SYMBOL_INFO
, msg
);
932 XFREE(MTYPE_TMP
, msg
);
935 /* Print test error message if available. */
936 if (test
->state
!= TEST_SUCCESS
&& test
->error
)
937 printf("%s error: %s\n", OUT_SYMBOL_INFO
, test
->error
);
939 /* Print machine-readable result of test. */
940 printf("%s\n", test
->state
== TEST_SUCCESS
? "OK" : "failed");
942 /* Cleanup allocated memory. */
944 vty_close(test
->vty
);
948 list_delete(&test
->log
);
950 XFREE(MTYPE_TMP
, test
->desc
);
952 XFREE(MTYPE_TMP
, test
->error
);
953 XFREE(MTYPE_TMP
, test
);
956 static void test_peer_flags(struct test
*test
, struct test_peer_attr
*pa
,
957 struct peer
*peer
, bool exp_val
, bool exp_ovrd
)
959 bool exp_inv
, cur_val
, cur_ovrd
, cur_inv
;
961 /* Skip execution if test instance has previously failed. */
962 if (test
->state
!= TEST_SUCCESS
)
965 /* Detect if flag is meant to be inverted. */
966 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
967 exp_inv
= pa
->o
.invert_group
;
969 exp_inv
= pa
->o
.invert_peer
;
971 /* Flip expected value if flag is inverted. */
974 /* Fetch current state of value, override and invert flags. */
975 if (pa
->type
== PEER_AT_GLOBAL_FLAG
) {
976 cur_val
= !!CHECK_FLAG(peer
->flags
, pa
->u
.flag
);
977 cur_ovrd
= !!CHECK_FLAG(peer
->flags_override
, pa
->u
.flag
);
978 cur_inv
= !!CHECK_FLAG(peer
->flags_invert
, pa
->u
.flag
);
979 } else /* if (pa->type == PEER_AT_AF_FLAG) */ {
980 cur_val
= !!CHECK_FLAG(peer
->af_flags
[pa
->afi
][pa
->safi
],
982 cur_ovrd
= !!CHECK_FLAG(
983 peer
->af_flags_override
[pa
->afi
][pa
->safi
], pa
->u
.flag
);
984 cur_inv
= !!CHECK_FLAG(peer
->af_flags_invert
[pa
->afi
][pa
->safi
],
988 /* Assert expected flag states. */
989 TEST_ASSERT_EQ(test
, cur_val
, exp_val
);
990 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
991 TEST_ASSERT_EQ(test
, cur_inv
, exp_inv
);
994 static void test_af_filter(struct test
*test
, struct test_peer_attr
*pa
,
995 struct peer
*peer
, bool exp_state
, bool exp_ovrd
)
998 struct bgp_filter
*filter
;
1000 /* Skip execution if test instance has previously failed. */
1001 if (test
->state
!= TEST_SUCCESS
)
1004 /* Fetch and assert current state of override flag. */
1005 cur_ovrd
= !!CHECK_FLAG(
1006 peer
->filter_override
[pa
->afi
][pa
->safi
][pa
->u
.filter
.direct
],
1009 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1011 /* Assert that map/list matches expected state (set/unset). */
1012 filter
= &peer
->filter
[pa
->afi
][pa
->safi
];
1014 switch (pa
->u
.filter
.flag
) {
1015 case PEER_FT_DISTRIBUTE_LIST
:
1016 TEST_ASSERT_EQ(test
,
1017 !!(filter
->dlist
[pa
->u
.filter
.direct
].name
),
1020 case PEER_FT_FILTER_LIST
:
1021 TEST_ASSERT_EQ(test
,
1022 !!(filter
->aslist
[pa
->u
.filter
.direct
].name
),
1025 case PEER_FT_PREFIX_LIST
:
1026 TEST_ASSERT_EQ(test
,
1027 !!(filter
->plist
[pa
->u
.filter
.direct
].name
),
1030 case PEER_FT_ROUTE_MAP
:
1031 TEST_ASSERT_EQ(test
, !!(filter
->map
[pa
->u
.filter
.direct
].name
),
1034 case PEER_FT_UNSUPPRESS_MAP
:
1035 TEST_ASSERT_EQ(test
, !!(filter
->usmap
.name
), exp_state
);
1040 static void test_custom(struct test
*test
, struct test_peer_attr
*pa
,
1041 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1045 char *handler_error
;
1047 for (i
= 0; i
< TEST_HANDLER_MAX
; i
++) {
1048 /* Skip execution if test instance has previously failed. */
1049 if (test
->state
!= TEST_SUCCESS
)
1052 /* Skip further execution if handler is undefined. */
1053 if (!pa
->handlers
[i
])
1056 /* Execute custom handler. */
1057 pa
->handlers
[i
](test
, pa
, peer
, group
, peer_set
, group_set
);
1058 if (test
->state
!= TEST_SUCCESS
) {
1059 test
->state
= TEST_CUSTOM_ERROR
;
1060 handler_error
= test
->error
;
1061 test
->error
= asprintfrr(MTYPE_TMP
,
1062 "custom handler failed: %s",
1064 XFREE(MTYPE_TMP
, handler_error
);
1070 static void test_process(struct test
*test
, struct test_peer_attr
*pa
,
1071 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1075 case PEER_AT_GLOBAL_FLAG
:
1076 case PEER_AT_AF_FLAG
:
1079 peer_set
|| (peer_group_active(peer
) && group_set
),
1081 test_peer_flags(test
, pa
, group
, group_set
, false);
1084 case PEER_AT_AF_FILTER
:
1087 peer_set
|| (peer_group_active(peer
) && group_set
),
1089 test_af_filter(test
, pa
, group
, group_set
, false);
1092 case PEER_AT_GLOBAL_CUSTOM
:
1093 case PEER_AT_AF_CUSTOM
:
1095 * Do nothing here - a custom handler can be executed, but this
1096 * is not required. This will allow defining peer attributes
1097 * which shall not be checked for flag/filter/other internal
1103 test
->state
= TEST_INTERNAL_ERROR
;
1104 test
->error
= asprintfrr(
1105 MTYPE_TMP
, "invalid attribute type: %d", pa
->type
);
1109 /* Attempt to call a custom handler if set for further processing. */
1110 test_custom(test
, pa
, peer
, group
, peer_set
, group_set
);
1113 static void test_peer_attr(struct test
*test
, struct test_peer_attr
*pa
)
1117 const char *ecp
= pa
->o
.invert_peer
? "no " : "";
1118 const char *dcp
= pa
->o
.invert_peer
? "" : "no ";
1119 const char *ecg
= pa
->o
.invert_group
? "no " : "";
1120 const char *dcg
= pa
->o
.invert_group
? "" : "no ";
1121 const char *peer_cmd
= pa
->peer_cmd
?: pa
->cmd
;
1122 const char *group_cmd
= pa
->group_cmd
?: pa
->cmd
;
1123 struct peer
*p
= test
->peer
;
1124 struct peer_group
*g
= test
->group
;
1126 /* Determine type and if test is address-family relevant */
1127 type
= str_from_attr_type(pa
->type
);
1129 test
->state
= TEST_INTERNAL_ERROR
;
1130 test
->error
= asprintfrr(
1131 MTYPE_TMP
, "invalid attribute type: %d", pa
->type
);
1136 * =====================================================================
1137 * Test Case Suite 1: Config persistence after adding peer to group
1139 * Example: If a peer attribute has value [1] and a group attribute has
1140 * value [2], the peer attribute value should be persisted when the peer
1141 * gets added to the peer-group.
1143 * This test suite is meant to test the group2peer functions which can
1144 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1146 * =====================================================================
1149 /* Test Preparation: Switch and activate address-family. */
1150 if (!is_attr_type_global(pa
->type
)) {
1151 test_log(test
, "prepare: switch address-family to [%s]",
1152 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1153 test_execute(test
, "address-family %s %s",
1154 str_from_afi(pa
->afi
), safi2str(pa
->safi
));
1155 test_execute(test
, "neighbor %s activate", g
->name
);
1156 test_execute(test
, "neighbor %s activate", p
->host
);
1159 /* Skip peer-group to peer transfer test cases if requested. */
1160 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SUCCESS
)
1161 test
->state
= TEST_SKIPPING
;
1163 /* Test Case: Set flag on BGP peer. */
1164 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1166 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1167 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1168 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1169 test_process(test
, pa
, p
, g
->conf
, true, false);
1171 /* Test Case: Set flag on BGP peer-group. */
1172 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1174 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1175 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1176 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1177 test_process(test
, pa
, p
, g
->conf
, true, true);
1179 /* Test Case: Add BGP peer to peer-group. */
1180 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1182 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1183 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1184 p
->conf_if
? "interface " : "", g
->name
);
1185 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1186 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1187 test_process(test
, pa
, p
, g
->conf
, true, true);
1189 /* Test Case: Unset flag on BGP peer-group. */
1190 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1191 group_cmd
, g
->name
);
1192 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1193 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1194 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1195 test_process(test
, pa
, p
, g
->conf
, true, false);
1198 * =====================================================================
1199 * Test Case Suite 2: Config inheritance after adding peer to group
1201 * Example: If a peer attribute has not been set and a group attribute
1202 * has a value of [2], the group attribute should be inherited to the
1203 * peer without flagging the newly set value as overridden.
1205 * This test suite is meant to test the group2peer functions which can
1206 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1208 * =====================================================================
1211 /* Test Preparation: Re-initialize test environment. */
1212 test_initialize(test
);
1216 /* Test Preparation: Switch and activate address-family. */
1217 if (!is_attr_type_global(pa
->type
)) {
1218 test_log(test
, "prepare: switch address-family to [%s]",
1219 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1220 test_execute(test
, "address-family %s %s",
1221 str_from_afi(pa
->afi
), safi2str(pa
->safi
));
1222 test_execute(test
, "neighbor %s activate", g
->name
);
1223 test_execute(test
, "neighbor %s activate", p
->host
);
1226 /* Test Case: Set flag on BGP peer-group. */
1227 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1229 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1230 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1231 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1232 test_process(test
, pa
, p
, g
->conf
, false, true);
1234 /* Test Case: Add BGP peer to peer-group. */
1235 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1237 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1238 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1239 p
->conf_if
? "interface " : "", g
->name
);
1240 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1241 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1242 test_process(test
, pa
, p
, g
->conf
, false, true);
1244 /* Stop skipping test cases if previously enabled. */
1245 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SKIPPING
)
1246 test
->state
= TEST_SUCCESS
;
1249 * =====================================================================
1250 * Test Case Suite 3: Miscellaneous flag checks
1252 * This test suite does not focus on initial peer-group inheritance and
1253 * instead executes various different commands to set/unset attributes
1254 * on both peer- and group-level. These checks should always be executed
1256 * =====================================================================
1259 /* Test Preparation: Re-initialize test environment. */
1260 test_initialize(test
);
1264 /* Test Preparation: Switch and activate address-family. */
1265 if (!is_attr_type_global(pa
->type
)) {
1266 test_log(test
, "prepare: switch address-family to [%s]",
1267 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1268 test_execute(test
, "address-family %s %s",
1269 str_from_afi(pa
->afi
), safi2str(pa
->safi
));
1270 test_execute(test
, "neighbor %s activate", g
->name
);
1271 test_execute(test
, "neighbor %s activate", p
->host
);
1274 /* Test Case: Set flag on BGP peer. */
1275 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1277 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1278 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1279 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1280 test_process(test
, pa
, p
, g
->conf
, true, false);
1282 /* Test Case: Add BGP peer to peer-group. */
1283 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1285 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1286 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1287 p
->conf_if
? "interface " : "", g
->name
);
1288 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1289 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1290 test_process(test
, pa
, p
, g
->conf
, true, false);
1292 /* Test Case: Re-add BGP peer to peer-group. */
1293 test_log(test
, "case %02d: re-add peer [%s] to group [%s]", tc
++,
1295 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1296 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1297 p
->conf_if
? "interface " : "", g
->name
);
1298 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1299 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1300 test_process(test
, pa
, p
, g
->conf
, true, false);
1302 /* Test Case: Set flag on BGP peer-group. */
1303 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1305 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1306 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1307 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1308 test_process(test
, pa
, p
, g
->conf
, true, true);
1310 /* Test Case: Unset flag on BGP peer-group. */
1311 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1312 group_cmd
, g
->name
);
1313 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1314 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1315 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1316 test_process(test
, pa
, p
, g
->conf
, true, false);
1318 /* Test Case: Set flag on BGP peer-group. */
1319 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1321 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1322 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1323 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1324 test_process(test
, pa
, p
, g
->conf
, true, true);
1326 /* Test Case: Re-set flag on BGP peer. */
1327 test_log(test
, "case %02d: re-set %s [%s] on [%s]", tc
++, type
,
1329 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1330 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1331 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1332 test_process(test
, pa
, p
, g
->conf
, true, true);
1334 /* Test Case: Unset flag on BGP peer. */
1335 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1337 test_execute(test
, "%sneighbor %s %s", dcp
, p
->host
, peer_cmd
);
1338 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1339 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1340 test_process(test
, pa
, p
, g
->conf
, false, true);
1342 /* Test Case: Unset flag on BGP peer-group. */
1343 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1344 group_cmd
, g
->name
);
1345 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1346 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1347 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1348 test_process(test
, pa
, p
, g
->conf
, false, false);
1350 /* Test Case: Set flag on BGP peer. */
1351 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1353 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1354 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1355 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1356 test_process(test
, pa
, p
, g
->conf
, true, false);
1359 static void bgp_startup(void)
1362 zlog_aux_init("NONE: ", LOG_DEBUG
);
1363 zprivs_preinit(&bgpd_privs
);
1364 zprivs_init(&bgpd_privs
);
1366 master
= event_master_create(NULL
);
1367 nb_init(master
, NULL
, 0, false);
1368 bgp_master_init(master
, BGP_SOCKET_SNDBUF_SIZE
, list_new());
1369 bgp_option_set(BGP_OPT_NO_LISTEN
);
1370 vrf_init(NULL
, NULL
, NULL
, NULL
);
1376 static void bgp_shutdown(void)
1379 struct listnode
*node
, *nnode
;
1383 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
1387 bgp_route_map_terminate();
1389 bgp_pthreads_finish();
1390 access_list_add_hook(NULL
);
1391 access_list_delete_hook(NULL
);
1392 access_list_reset();
1393 as_list_add_hook(NULL
);
1394 as_list_delete_hook(NULL
);
1396 prefix_list_add_hook(NULL
);
1397 prefix_list_delete_hook(NULL
);
1398 prefix_list_reset();
1399 community_list_terminate(bgp_clist
);
1401 #ifdef ENABLE_BGP_VNC
1402 vnc_zebra_destroy();
1404 bgp_zebra_destroy();
1406 bf_free(bm
->rd_idspace
);
1407 list_delete(&bm
->bgp
);
1408 memset(bm
, 0, sizeof(*bm
));
1414 zprivs_terminate(&bgpd_privs
);
1415 event_master_free(master
);
1422 struct list
*pa_list
;
1423 struct test_peer_attr
*pa
, *pac
;
1424 struct listnode
*node
, *nnode
;
1428 pa_list
= list_new();
1430 while (test_peer_attrs
[i
].cmd
) {
1431 pa
= &test_peer_attrs
[i
++];
1433 /* Just copy the peer attribute structure for global flags. */
1434 if (is_attr_type_global(pa
->type
)) {
1435 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1436 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1437 listnode_add(pa_list
, pac
);
1441 /* Fallback to default families if not specified. */
1442 if (!pa
->families
[0].afi
&& !pa
->families
[0].safi
)
1443 memcpy(&pa
->families
, test_default_families
,
1444 sizeof(test_default_families
));
1446 /* Add peer attribute definition for each address family. */
1448 while (pa
->families
[ii
].afi
&& pa
->families
[ii
].safi
) {
1449 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1450 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1452 pac
->afi
= pa
->families
[ii
].afi
;
1453 pac
->safi
= pa
->families
[ii
].safi
;
1454 listnode_add(pa_list
, pac
);
1460 for (ALL_LIST_ELEMENTS(pa_list
, node
, nnode
, pa
)) {
1464 /* Build test description string. */
1465 if (pa
->afi
&& pa
->safi
)
1466 desc
= asprintfrr(MTYPE_TMP
, "peer\\%s-%s\\%s",
1467 str_from_afi(pa
->afi
),
1468 safi2str(pa
->safi
), pa
->cmd
);
1470 desc
= asprintfrr(MTYPE_TMP
, "peer\\%s", pa
->cmd
);
1472 /* Initialize new test instance. */
1473 test
= test_new(desc
, pa
->o
.use_ibgp
, pa
->o
.use_iface_peer
);
1474 XFREE(MTYPE_TMP
, desc
);
1476 /* Execute tests and finish test instance. */
1477 test_peer_attr(test
, pa
);
1480 /* Print empty line as spacer. */
1483 /* Free memory used for peer-attr declaration. */
1484 XFREE(MTYPE_TMP
, pa
);
1487 list_delete(&pa_list
);