2 * BGP Peer Attribute Unit Tests
3 * Copyright (C) 2018 Pascal Mathis
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with this program; see the file COPYING; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include "bgpd/bgpd.h"
24 #include "bgpd/bgp_attr.h"
25 #include "bgpd/bgp_regex.h"
26 #include "bgpd/bgp_clist.h"
27 #include "bgpd/bgp_dump.h"
28 #include "bgpd/bgp_filter.h"
29 #include "bgpd/bgp_route.h"
30 #include "bgpd/bgp_vty.h"
31 #include "bgpd/bgp_zebra.h"
34 #include "bgpd/rfapi/rfapi_backend.h"
37 #define OUT_SYMBOL_INFO "\u25ba"
38 #define OUT_SYMBOL_OK "\u2714"
39 #define OUT_SYMBOL_NOK "\u2716"
41 #define TEST_ASSERT(T, C) \
43 if ((T)->state != TEST_SUCCESS || (C)) \
45 (T)->state = TEST_ASSERT_ERROR; \
46 (T)->error = str_printf("assertion failed: %s (%s:%d)", (#C), \
47 __FILE__, __LINE__); \
50 #define TEST_ASSERT_EQ(T, A, B) \
52 if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
54 (T)->state = TEST_ASSERT_ERROR; \
55 (T)->error = str_printf( \
56 "assertion failed: %s[%d] == [%d]%s (%s:%d)", (#A), \
57 (A), (B), (#B), __FILE__, __LINE__); \
60 #define TEST_HANDLER_MAX 5
61 #define TEST_HANDLER(name) _test_handler_##name
62 #define TEST_HANDLER_DECL(name) \
63 static void _test_handler_##name( \
64 struct test *test, struct test_peer_attr *pa, \
65 struct peer *peer, struct peer *group, bool peer_set, \
68 #define TEST_ATTR_HANDLER_DECL(name, attr, pval, gval) \
69 TEST_HANDLER_DECL(name) \
72 TEST_ASSERT_EQ(test, peer->attr, (pval)); \
73 else if (peer_group_active(peer) && group_set) \
74 TEST_ASSERT_EQ(test, peer->attr, (gval)); \
76 TEST_ASSERT_EQ(test, group->attr, (gval)); \
78 TEST_HANDLER_DECL(name)
80 #define TEST_STR_ATTR_HANDLER_DECL(name, attr, pval, gval) \
81 TEST_HANDLER_DECL(name) \
84 TEST_ASSERT(test, peer->attr != NULL); \
85 TEST_ASSERT(test, !strcmp(peer->attr, (pval))); \
86 } else if (peer_group_active(peer) && group_set) { \
87 TEST_ASSERT(test, peer->attr != NULL); \
88 TEST_ASSERT(test, !strcmp(peer->attr, (gval))); \
91 TEST_ASSERT(test, group->attr != NULL); \
92 TEST_ASSERT(test, !strcmp(group->attr, (gval))); \
95 TEST_HANDLER_DECL(name)
97 #define TEST_SU_ATTR_HANDLER_DECL(name, attr, pval, gval) \
98 TEST_HANDLER_DECL(name) \
100 union sockunion su; \
102 str2sockunion(pval, &su); \
103 TEST_ASSERT(test, !sockunion_cmp(peer->attr, &su)); \
104 } else if (peer_group_active(peer) && group_set) { \
105 str2sockunion(gval, &su); \
106 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
109 str2sockunion(gval, &su); \
110 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
113 TEST_HANDLER_DECL(name)
115 /* Required variables to link in libbgp */
116 struct zebra_privs_t bgpd_privs
= {0};
117 struct thread_master
*master
;
129 enum test_peer_attr_type
{
131 PEER_AT_AF_FILTER
= 1,
132 PEER_AT_AF_CUSTOM
= 2,
133 PEER_AT_GLOBAL_FLAG
= 3,
134 PEER_AT_GLOBAL_CUSTOM
= 4
138 enum test_state state
;
146 struct peer_group
*group
;
157 const char *peer_address
;
158 const char *peer_interface
;
159 const char *peer_group
;
162 struct test_peer_family
{
167 struct test_peer_attr
{
169 const char *peer_cmd
;
170 const char *group_cmd
;
172 enum test_peer_attr_type type
;
185 bool skip_xfer_cases
;
190 struct test_peer_family families
[AFI_MAX
* SAFI_MAX
];
192 void (*handlers
[TEST_HANDLER_MAX
])(struct test
*test
,
193 struct test_peer_attr
*pa
,
195 struct peer
*group
, bool peer_set
,
199 static struct test_config cfg
= {
202 .peer_address
= "1.1.1.1",
203 .peer_interface
= "IP-TEST",
204 .peer_group
= "PG-TEST",
207 static struct test_peer_family test_default_families
[] = {
208 {.afi
= AFI_IP
, .safi
= SAFI_UNICAST
},
209 {.afi
= AFI_IP
, .safi
= SAFI_MULTICAST
},
210 {.afi
= AFI_IP6
, .safi
= SAFI_UNICAST
},
211 {.afi
= AFI_IP6
, .safi
= SAFI_MULTICAST
},
214 static char *str_vprintf(const char *fmt
, va_list ap
)
223 ret
= vsnprintf(buf
, buf_size
, fmt
, apc
);
226 if (ret
>= 0 && ret
< buf_size
)
234 buf
= XREALLOC(MTYPE_TMP
, buf
, buf_size
);
240 static char *str_printf(const char *fmt
, ...)
246 buf
= str_vprintf(fmt
, ap
);
252 TEST_ATTR_HANDLER_DECL(advertisement_interval
, v_routeadv
, 10, 20);
253 TEST_STR_ATTR_HANDLER_DECL(password
, password
, "FRR-Peer", "FRR-Group");
254 TEST_ATTR_HANDLER_DECL(local_as
, change_local_as
, 1, 2);
255 TEST_ATTR_HANDLER_DECL(timers_1
, keepalive
, 10, 20);
256 TEST_ATTR_HANDLER_DECL(timers_2
, holdtime
, 30, 60);
257 TEST_SU_ATTR_HANDLER_DECL(update_source_su
, update_source
, "255.255.255.1",
259 TEST_STR_ATTR_HANDLER_DECL(update_source_if
, update_if
, "IF-PEER", "IF-GROUP");
261 TEST_ATTR_HANDLER_DECL(allowas_in
, allowas_in
[pa
->afi
][pa
->safi
], 1, 2);
262 TEST_STR_ATTR_HANDLER_DECL(default_originate_route_map
,
263 default_rmap
[pa
->afi
][pa
->safi
].name
, "RM-PEER",
265 TEST_STR_ATTR_HANDLER_DECL(
267 filter
[pa
->afi
][pa
->safi
].dlist
[pa
->u
.filter
.direct
].name
, "DL-PEER",
269 TEST_STR_ATTR_HANDLER_DECL(
270 filter_list
, filter
[pa
->afi
][pa
->safi
].aslist
[pa
->u
.filter
.direct
].name
,
271 "FL-PEER", "FL-GROUP");
272 TEST_ATTR_HANDLER_DECL(maximum_prefix
, pmax
[pa
->afi
][pa
->safi
], 10, 20);
273 TEST_ATTR_HANDLER_DECL(maximum_prefix_threshold
,
274 pmax_threshold
[pa
->afi
][pa
->safi
], 1, 2);
275 TEST_ATTR_HANDLER_DECL(maximum_prefix_restart
, pmax_restart
[pa
->afi
][pa
->safi
],
277 TEST_STR_ATTR_HANDLER_DECL(
278 prefix_list
, filter
[pa
->afi
][pa
->safi
].plist
[pa
->u
.filter
.direct
].name
,
279 "PL-PEER", "PL-GROUP");
280 TEST_STR_ATTR_HANDLER_DECL(
281 route_map
, filter
[pa
->afi
][pa
->safi
].map
[pa
->u
.filter
.direct
].name
,
282 "RM-PEER", "RM-GROUP");
283 TEST_STR_ATTR_HANDLER_DECL(unsuppress_map
, filter
[pa
->afi
][pa
->safi
].usmap
.name
,
284 "UM-PEER", "UM-GROUP");
285 TEST_ATTR_HANDLER_DECL(weight
, weight
[pa
->afi
][pa
->safi
], 100, 200);
287 /* clang-format off */
288 static struct test_peer_attr test_peer_attrs
[] = {
289 /* Peer Attributes */
291 .cmd
= "advertisement-interval",
292 .peer_cmd
= "advertisement-interval 10",
293 .group_cmd
= "advertisement-interval 20",
294 .u
.flag
= PEER_FLAG_ROUTEADV
,
295 .type
= PEER_AT_GLOBAL_FLAG
,
296 .handlers
[0] = TEST_HANDLER(advertisement_interval
),
299 .cmd
= "capability dynamic",
300 .u
.flag
= PEER_FLAG_DYNAMIC_CAPABILITY
,
301 .type
= PEER_AT_GLOBAL_FLAG
,
304 .cmd
= "capability extended-nexthop",
305 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
306 .type
= PEER_AT_GLOBAL_FLAG
,
309 .cmd
= "capability extended-nexthop",
310 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
311 .type
= PEER_AT_GLOBAL_FLAG
,
312 .o
.invert_peer
= true,
313 .o
.use_iface_peer
= true,
316 .cmd
= "description",
317 .peer_cmd
= "description FRR Peer",
318 .group_cmd
= "description FRR Group",
319 .type
= PEER_AT_GLOBAL_CUSTOM
,
322 .cmd
= "disable-connected-check",
323 .u
.flag
= PEER_FLAG_DISABLE_CONNECTED_CHECK
,
324 .type
= PEER_AT_GLOBAL_FLAG
,
327 .cmd
= "dont-capability-negotiate",
328 .u
.flag
= PEER_FLAG_DONT_CAPABILITY
,
329 .type
= PEER_AT_GLOBAL_FLAG
,
332 .cmd
= "enforce-first-as",
333 .u
.flag
= PEER_FLAG_ENFORCE_FIRST_AS
,
334 .type
= PEER_AT_GLOBAL_FLAG
,
338 .peer_cmd
= "local-as 1",
339 .group_cmd
= "local-as 2",
340 .u
.flag
= PEER_FLAG_LOCAL_AS
,
341 .type
= PEER_AT_GLOBAL_FLAG
,
342 .handlers
[0] = TEST_HANDLER(local_as
),
345 .cmd
= "local-as 1 no-prepend",
346 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_NO_PREPEND
,
347 .type
= PEER_AT_GLOBAL_FLAG
,
350 .cmd
= "local-as 1 no-prepend replace-as",
351 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_REPLACE_AS
,
352 .type
= PEER_AT_GLOBAL_FLAG
,
355 .cmd
= "override-capability",
356 .u
.flag
= PEER_FLAG_OVERRIDE_CAPABILITY
,
357 .type
= PEER_AT_GLOBAL_FLAG
,
361 .u
.flag
= PEER_FLAG_PASSIVE
,
362 .type
= PEER_AT_GLOBAL_FLAG
,
366 .peer_cmd
= "password FRR-Peer",
367 .group_cmd
= "password FRR-Group",
368 .u
.flag
= PEER_FLAG_PASSWORD
,
369 .type
= PEER_AT_GLOBAL_FLAG
,
370 .handlers
[0] = TEST_HANDLER(password
),
374 .u
.flag
= PEER_FLAG_SHUTDOWN
,
375 .type
= PEER_AT_GLOBAL_FLAG
,
378 .cmd
= "strict-capability-match",
379 .u
.flag
= PEER_FLAG_STRICT_CAP_MATCH
,
380 .type
= PEER_AT_GLOBAL_FLAG
,
384 .peer_cmd
= "timers 10 30",
385 .group_cmd
= "timers 20 60",
386 .u
.flag
= PEER_FLAG_TIMER
,
387 .type
= PEER_AT_GLOBAL_FLAG
,
388 .handlers
[0] = TEST_HANDLER(timers_1
),
389 .handlers
[1] = TEST_HANDLER(timers_2
),
392 .cmd
= "timers connect",
393 .peer_cmd
= "timers connect 10",
394 .group_cmd
= "timers connect 20",
395 .u
.flag
= PEER_FLAG_TIMER_CONNECT
,
396 .type
= PEER_AT_GLOBAL_FLAG
,
399 .cmd
= "update-source",
400 .peer_cmd
= "update-source 255.255.255.1",
401 .group_cmd
= "update-source 255.255.255.2",
402 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
403 .type
= PEER_AT_GLOBAL_FLAG
,
404 .handlers
[0] = TEST_HANDLER(update_source_su
),
407 .cmd
= "update-source",
408 .peer_cmd
= "update-source IF-PEER",
409 .group_cmd
= "update-source IF-GROUP",
410 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
411 .type
= PEER_AT_GLOBAL_FLAG
,
412 .handlers
[0] = TEST_HANDLER(update_source_if
),
415 /* Address Family Attributes */
417 .cmd
= "addpath-tx-all-paths",
418 .u
.flag
= PEER_FLAG_ADDPATH_TX_ALL_PATHS
,
421 .cmd
= "addpath-tx-bestpath-per-AS",
422 .u
.flag
= PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS
,
426 .peer_cmd
= "allowas-in 1",
427 .group_cmd
= "allowas-in 2",
428 .u
.flag
= PEER_FLAG_ALLOWAS_IN
,
429 .handlers
[0] = TEST_HANDLER(allowas_in
),
432 .cmd
= "allowas-in origin",
433 .u
.flag
= PEER_FLAG_ALLOWAS_IN_ORIGIN
,
436 .cmd
= "as-override",
437 .u
.flag
= PEER_FLAG_AS_OVERRIDE
,
440 .cmd
= "attribute-unchanged as-path",
441 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
,
444 .cmd
= "attribute-unchanged next-hop",
445 .u
.flag
= PEER_FLAG_NEXTHOP_UNCHANGED
,
448 .cmd
= "attribute-unchanged med",
449 .u
.flag
= PEER_FLAG_MED_UNCHANGED
,
452 .cmd
= "attribute-unchanged as-path next-hop",
453 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
454 | PEER_FLAG_NEXTHOP_UNCHANGED
,
457 .cmd
= "attribute-unchanged as-path med",
458 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
459 | PEER_FLAG_MED_UNCHANGED
,
462 .cmd
= "attribute-unchanged as-path next-hop med",
463 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
464 | PEER_FLAG_NEXTHOP_UNCHANGED
465 | PEER_FLAG_MED_UNCHANGED
,
468 .cmd
= "capability orf prefix-list send",
469 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
,
472 .cmd
= "capability orf prefix-list receive",
473 .u
.flag
= PEER_FLAG_ORF_PREFIX_RM
,
476 .cmd
= "capability orf prefix-list both",
477 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
| PEER_FLAG_ORF_PREFIX_RM
,
480 .cmd
= "default-originate",
481 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
484 .cmd
= "default-originate route-map",
485 .peer_cmd
= "default-originate route-map RM-PEER",
486 .group_cmd
= "default-originate route-map RM-GROUP",
487 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
488 .handlers
[0] = TEST_HANDLER(default_originate_route_map
),
491 .cmd
= "distribute-list",
492 .peer_cmd
= "distribute-list DL-PEER in",
493 .group_cmd
= "distribute-list DL-GROUP in",
494 .type
= PEER_AT_AF_FILTER
,
495 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
496 .u
.filter
.direct
= FILTER_IN
,
497 .handlers
[0] = TEST_HANDLER(distribute_list
),
500 .cmd
= "distribute-list",
501 .peer_cmd
= "distribute-list DL-PEER out",
502 .group_cmd
= "distribute-list DL-GROUP out",
503 .type
= PEER_AT_AF_FILTER
,
504 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
505 .u
.filter
.direct
= FILTER_OUT
,
506 .handlers
[0] = TEST_HANDLER(distribute_list
),
509 .cmd
= "filter-list",
510 .peer_cmd
= "filter-list FL-PEER in",
511 .group_cmd
= "filter-list FL-GROUP in",
512 .type
= PEER_AT_AF_FILTER
,
513 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
514 .u
.filter
.direct
= FILTER_IN
,
515 .handlers
[0] = TEST_HANDLER(filter_list
),
518 .cmd
= "filter-list",
519 .peer_cmd
= "filter-list FL-PEER out",
520 .group_cmd
= "filter-list FL-GROUP out",
521 .type
= PEER_AT_AF_FILTER
,
522 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
523 .u
.filter
.direct
= FILTER_OUT
,
524 .handlers
[0] = TEST_HANDLER(filter_list
),
527 .cmd
= "maximum-prefix",
528 .peer_cmd
= "maximum-prefix 10",
529 .group_cmd
= "maximum-prefix 20",
530 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
531 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
534 .cmd
= "maximum-prefix",
535 .peer_cmd
= "maximum-prefix 10 restart 100",
536 .group_cmd
= "maximum-prefix 20 restart 200",
537 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
538 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
539 .handlers
[1] = TEST_HANDLER(maximum_prefix_restart
),
542 .cmd
= "maximum-prefix",
543 .peer_cmd
= "maximum-prefix 10 1 restart 100",
544 .group_cmd
= "maximum-prefix 20 2 restart 200",
545 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
546 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
547 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
548 .handlers
[2] = TEST_HANDLER(maximum_prefix_restart
),
551 .cmd
= "maximum-prefix",
552 .peer_cmd
= "maximum-prefix 10 warning-only",
553 .group_cmd
= "maximum-prefix 20 warning-only",
554 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
555 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
558 .cmd
= "maximum-prefix",
559 .peer_cmd
= "maximum-prefix 10 1 warning-only",
560 .group_cmd
= "maximum-prefix 20 2 warning-only",
561 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
562 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
563 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
566 .cmd
= "next-hop-self",
567 .u
.flag
= PEER_FLAG_NEXTHOP_SELF
,
570 .cmd
= "next-hop-self force",
571 .u
.flag
= PEER_FLAG_FORCE_NEXTHOP_SELF
,
574 .cmd
= "prefix-list",
575 .peer_cmd
= "prefix-list PL-PEER in",
576 .group_cmd
= "prefix-list PL-GROUP in",
577 .type
= PEER_AT_AF_FILTER
,
578 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
579 .u
.filter
.direct
= FILTER_IN
,
580 .handlers
[0] = TEST_HANDLER(prefix_list
),
583 .cmd
= "prefix-list",
584 .peer_cmd
= "prefix-list PL-PEER out",
585 .group_cmd
= "prefix-list PL-GROUP out",
586 .type
= PEER_AT_AF_FILTER
,
587 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
588 .u
.filter
.direct
= FILTER_OUT
,
589 .handlers
[0] = TEST_HANDLER(prefix_list
),
592 .cmd
= "remove-private-AS",
593 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
,
596 .cmd
= "remove-private-AS all",
597 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
598 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL
,
601 .cmd
= "remove-private-AS replace-AS",
602 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
603 | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
,
606 .cmd
= "remove-private-AS all replace-AS",
607 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
,
611 .peer_cmd
= "route-map RM-PEER in",
612 .group_cmd
= "route-map RM-GROUP in",
613 .type
= PEER_AT_AF_FILTER
,
614 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
615 .u
.filter
.direct
= FILTER_IN
,
616 .handlers
[0] = TEST_HANDLER(route_map
),
620 .peer_cmd
= "route-map RM-PEER out",
621 .group_cmd
= "route-map RM-GROUP out",
622 .type
= PEER_AT_AF_FILTER
,
623 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
624 .u
.filter
.direct
= FILTER_OUT
,
625 .handlers
[0] = TEST_HANDLER(route_map
),
628 .cmd
= "route-reflector-client",
629 .u
.flag
= PEER_FLAG_REFLECTOR_CLIENT
,
631 .o
.skip_xfer_cases
= true,
634 .cmd
= "route-server-client",
635 .u
.flag
= PEER_FLAG_RSERVER_CLIENT
,
638 .cmd
= "send-community",
639 .u
.flag
= PEER_FLAG_SEND_COMMUNITY
,
640 .o
.invert_peer
= true,
641 .o
.invert_group
= true,
644 .cmd
= "send-community extended",
645 .u
.flag
= PEER_FLAG_SEND_EXT_COMMUNITY
,
646 .o
.invert_peer
= true,
647 .o
.invert_group
= true,
650 .cmd
= "send-community large",
651 .u
.flag
= PEER_FLAG_SEND_LARGE_COMMUNITY
,
652 .o
.invert_peer
= true,
653 .o
.invert_group
= true,
656 .cmd
= "soft-reconfiguration inbound",
657 .u
.flag
= PEER_FLAG_SOFT_RECONFIG
,
660 .cmd
= "unsuppress-map",
661 .peer_cmd
= "unsuppress-map UM-PEER",
662 .group_cmd
= "unsuppress-map UM-GROUP",
663 .type
= PEER_AT_AF_FILTER
,
664 .u
.filter
.flag
= PEER_FT_UNSUPPRESS_MAP
,
665 .u
.filter
.direct
= 0,
666 .handlers
[0] = TEST_HANDLER(unsuppress_map
),
670 .peer_cmd
= "weight 100",
671 .group_cmd
= "weight 200",
672 .u
.flag
= PEER_FLAG_WEIGHT
,
673 .handlers
[0] = TEST_HANDLER(weight
),
677 /* clang-format on */
679 static const char *str_from_afi(afi_t afi
)
687 return "<unknown AFI>";
691 static const char *str_from_safi(safi_t safi
)
699 return "<unknown SAFI>";
703 static const char *str_from_attr_type(enum test_peer_attr_type at
)
706 case PEER_AT_GLOBAL_FLAG
:
708 case PEER_AT_AF_FLAG
:
710 case PEER_AT_AF_FILTER
:
712 case PEER_AT_GLOBAL_CUSTOM
:
713 case PEER_AT_AF_CUSTOM
:
720 static bool is_attr_type_global(enum test_peer_attr_type at
)
722 return at
== PEER_AT_GLOBAL_FLAG
|| at
== PEER_AT_GLOBAL_CUSTOM
;
725 static void test_log(struct test
*test
, const char *fmt
, ...)
729 /* Skip logging if test instance has previously failed. */
730 if (test
->state
!= TEST_SUCCESS
)
733 /* Store formatted log message. */
735 listnode_add(test
->log
, str_vprintf(fmt
, ap
));
739 static void test_execute(struct test
*test
, const char *fmt
, ...)
746 /* Skip execution if test instance has previously failed. */
747 if (test
->state
!= TEST_SUCCESS
)
750 /* Format command string with variadic arguments. */
752 cmd
= str_vprintf(fmt
, ap
);
755 test
->state
= TEST_INTERNAL_ERROR
;
757 str_printf("could not format command string [%s]", fmt
);
761 /* Tokenize formatted command string. */
762 vline
= cmd_make_strvec(cmd
);
764 test
->state
= TEST_INTERNAL_ERROR
;
765 test
->error
= str_printf(
766 "tokenizing command string [%s] returned empty result",
768 XFREE(MTYPE_TMP
, cmd
);
773 /* Execute command (non-strict). */
774 ret
= cmd_execute_command(vline
, test
->vty
, NULL
, 0);
775 if (ret
!= CMD_SUCCESS
) {
776 test
->state
= TEST_COMMAND_ERROR
;
777 test
->error
= str_printf(
778 "execution of command [%s] has failed with code [%d]",
783 cmd_free_strvec(vline
);
784 XFREE(MTYPE_TMP
, cmd
);
787 static void test_config(struct test
*test
, const char *fmt
, bool invert
,
795 /* Skip execution if test instance has previously failed. */
796 if (test
->state
!= TEST_SUCCESS
)
799 /* Format matcher string with variadic arguments. */
801 matcher
= str_vprintf(fmt
, apc
);
804 test
->state
= TEST_INTERNAL_ERROR
;
806 str_printf("could not format matcher string [%s]", fmt
);
810 /* Fetch BGP configuration into buffer. */
811 bgp_config_write(test
->vty
);
812 config
= buffer_getstr(test
->vty
->obuf
);
813 buffer_reset(test
->vty
->obuf
);
815 /* Match config against matcher. */
816 matched
= !!strstr(config
, matcher
);
817 if (!matched
&& !invert
) {
818 test
->state
= TEST_CONFIG_ERROR
;
819 test
->error
= str_printf("expected config [%s] to be present",
821 } else if (matched
&& invert
) {
822 test
->state
= TEST_CONFIG_ERROR
;
823 test
->error
= str_printf("expected config [%s] to be absent",
827 /* Free memory and return. */
828 XFREE(MTYPE_TMP
, matcher
);
829 XFREE(MTYPE_TMP
, config
);
832 static void test_config_present(struct test
*test
, const char *fmt
, ...)
837 test_config(test
, fmt
, false, ap
);
841 static void test_config_absent(struct test
*test
, const char *fmt
, ...)
846 test_config(test
, fmt
, true, ap
);
850 static void test_initialize(struct test
*test
)
854 /* Skip execution if test instance has previously failed. */
855 if (test
->state
!= TEST_SUCCESS
)
858 /* Log message about (re)-initialization */
859 test_log(test
, "prepare: %sinitialize bgp test environment",
860 test
->bgp
? "re-" : "");
862 /* Attempt gracefully to purge previous BGP configuration. */
863 test_execute(test
, "no router bgp");
864 test
->state
= TEST_SUCCESS
;
866 /* Initialize BGP test environment. */
867 test_execute(test
, "router bgp %d", cfg
.local_asn
);
868 test_execute(test
, "no bgp default ipv4-unicast");
869 test_execute(test
, "neighbor %s peer-group", cfg
.peer_group
);
870 if (test
->o
.use_iface_peer
) {
871 test_execute(test
, "neighbor %s interface", cfg
.peer_interface
);
872 test_execute(test
, "neighbor %s remote-as %d",
874 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
876 test_execute(test
, "neighbor %s remote-as %d", cfg
.peer_address
,
877 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
880 if (test
->state
!= TEST_SUCCESS
)
883 /* Fetch default BGP instance. */
884 test
->bgp
= bgp_get_default();
886 test
->state
= TEST_INTERNAL_ERROR
;
888 str_printf("could not retrieve default bgp instance");
892 /* Fetch peer instance. */
893 if (test
->o
.use_iface_peer
) {
895 peer_lookup_by_conf_if(test
->bgp
, cfg
.peer_interface
);
897 str2sockunion(cfg
.peer_address
, &su
);
898 test
->peer
= peer_lookup(test
->bgp
, &su
);
901 test
->state
= TEST_INTERNAL_ERROR
;
902 test
->error
= str_printf(
903 "could not retrieve instance of bgp peer [%s]",
908 /* Fetch peer-group instance. */
909 test
->group
= peer_group_lookup(test
->bgp
, cfg
.peer_group
);
911 test
->state
= TEST_INTERNAL_ERROR
;
912 test
->error
= str_printf(
913 "could not retrieve instance of bgp peer-group [%s]",
919 static struct test
*test_new(const char *desc
, bool use_ibgp
,
924 test
= XCALLOC(MTYPE_TMP
, sizeof(struct test
));
925 test
->state
= TEST_SUCCESS
;
926 test
->desc
= XSTRDUP(MTYPE_TMP
, desc
);
927 test
->log
= list_new();
928 test
->o
.use_ibgp
= use_ibgp
;
929 test
->o
.use_iface_peer
= use_iface_peer
;
931 test
->vty
= vty_new();
932 test
->vty
->type
= VTY_TERM
;
933 test
->vty
->node
= CONFIG_NODE
;
935 test_initialize(test
);
940 static void test_finish(struct test
*test
)
943 struct listnode
*node
, *nnode
;
945 /* Print test output header. */
946 printf("%s [test] %s\n",
947 (test
->state
== TEST_SUCCESS
) ? OUT_SYMBOL_OK
: OUT_SYMBOL_NOK
,
950 /* Print test log messages. */
951 for (ALL_LIST_ELEMENTS(test
->log
, node
, nnode
, msg
)) {
952 printf("%s %s\n", OUT_SYMBOL_INFO
, msg
);
953 XFREE(MTYPE_TMP
, msg
);
956 /* Print test error message if available. */
957 if (test
->state
!= TEST_SUCCESS
&& test
->error
)
958 printf("%s error: %s\n", OUT_SYMBOL_INFO
, test
->error
);
960 /* Print machine-readable result of test. */
961 printf("%s\n", test
->state
== TEST_SUCCESS
? "OK" : "failed");
963 /* Cleanup allocated memory. */
965 vty_close(test
->vty
);
969 list_delete_and_null(&test
->log
);
971 XFREE(MTYPE_TMP
, test
->desc
);
973 XFREE(MTYPE_TMP
, test
->error
);
974 XFREE(MTYPE_TMP
, test
);
977 static void test_peer_flags(struct test
*test
, struct test_peer_attr
*pa
,
978 struct peer
*peer
, bool exp_val
, bool exp_ovrd
)
980 bool exp_inv
, cur_val
, cur_ovrd
, cur_inv
;
982 /* Skip execution if test instance has previously failed. */
983 if (test
->state
!= TEST_SUCCESS
)
986 /* Detect if flag is meant to be inverted. */
987 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
988 exp_inv
= pa
->o
.invert_group
;
990 exp_inv
= pa
->o
.invert_peer
;
992 /* Flip expected value if flag is inverted. */
995 /* Fetch current state of value, override and invert flags. */
996 if (pa
->type
== PEER_AT_GLOBAL_FLAG
) {
997 cur_val
= !!CHECK_FLAG(peer
->flags
, pa
->u
.flag
);
998 cur_ovrd
= !!CHECK_FLAG(peer
->flags_override
, pa
->u
.flag
);
999 cur_inv
= !!CHECK_FLAG(peer
->flags_invert
, pa
->u
.flag
);
1000 } else /* if (pa->type == PEER_AT_AF_FLAG) */ {
1001 cur_val
= !!CHECK_FLAG(peer
->af_flags
[pa
->afi
][pa
->safi
],
1003 cur_ovrd
= !!CHECK_FLAG(
1004 peer
->af_flags_override
[pa
->afi
][pa
->safi
], pa
->u
.flag
);
1005 cur_inv
= !!CHECK_FLAG(peer
->af_flags_invert
[pa
->afi
][pa
->safi
],
1009 /* Assert expected flag states. */
1010 TEST_ASSERT_EQ(test
, cur_val
, exp_val
);
1011 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1012 TEST_ASSERT_EQ(test
, cur_inv
, exp_inv
);
1015 static void test_af_filter(struct test
*test
, struct test_peer_attr
*pa
,
1016 struct peer
*peer
, bool exp_state
, bool exp_ovrd
)
1019 struct bgp_filter
*filter
;
1021 /* Skip execution if test instance has previously failed. */
1022 if (test
->state
!= TEST_SUCCESS
)
1025 /* Fetch and assert current state of override flag. */
1026 cur_ovrd
= !!CHECK_FLAG(
1027 peer
->filter_override
[pa
->afi
][pa
->safi
][pa
->u
.filter
.direct
],
1030 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1032 /* Assert that map/list matches expected state (set/unset). */
1033 filter
= &peer
->filter
[pa
->afi
][pa
->safi
];
1035 switch (pa
->u
.filter
.flag
) {
1036 case PEER_FT_DISTRIBUTE_LIST
:
1037 TEST_ASSERT_EQ(test
,
1038 !!(filter
->dlist
[pa
->u
.filter
.direct
].name
),
1041 case PEER_FT_FILTER_LIST
:
1042 TEST_ASSERT_EQ(test
,
1043 !!(filter
->aslist
[pa
->u
.filter
.direct
].name
),
1046 case PEER_FT_PREFIX_LIST
:
1047 TEST_ASSERT_EQ(test
,
1048 !!(filter
->plist
[pa
->u
.filter
.direct
].name
),
1051 case PEER_FT_ROUTE_MAP
:
1052 TEST_ASSERT_EQ(test
, !!(filter
->map
[pa
->u
.filter
.direct
].name
),
1055 case PEER_FT_UNSUPPRESS_MAP
:
1056 TEST_ASSERT_EQ(test
, !!(filter
->usmap
.name
), exp_state
);
1061 static void test_custom(struct test
*test
, struct test_peer_attr
*pa
,
1062 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1066 char *handler_error
;
1068 for (i
= 0; i
< TEST_HANDLER_MAX
; i
++) {
1069 /* Skip execution if test instance has previously failed. */
1070 if (test
->state
!= TEST_SUCCESS
)
1073 /* Skip further execution if handler is undefined. */
1074 if (!pa
->handlers
[i
])
1077 /* Execute custom handler. */
1078 pa
->handlers
[i
](test
, pa
, peer
, group
, peer_set
, group_set
);
1079 if (test
->state
!= TEST_SUCCESS
) {
1080 test
->state
= TEST_CUSTOM_ERROR
;
1081 handler_error
= test
->error
;
1082 test
->error
= str_printf("custom handler failed: %s",
1084 XFREE(MTYPE_TMP
, handler_error
);
1090 static void test_process(struct test
*test
, struct test_peer_attr
*pa
,
1091 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1095 case PEER_AT_GLOBAL_FLAG
:
1096 case PEER_AT_AF_FLAG
:
1099 peer_set
|| (peer_group_active(peer
) && group_set
),
1101 test_peer_flags(test
, pa
, group
, group_set
, false);
1104 case PEER_AT_AF_FILTER
:
1107 peer_set
|| (peer_group_active(peer
) && group_set
),
1109 test_af_filter(test
, pa
, group
, group_set
, false);
1112 case PEER_AT_GLOBAL_CUSTOM
:
1113 case PEER_AT_AF_CUSTOM
:
1115 * Do nothing here - a custom handler can be executed, but this
1116 * is not required. This will allow defining peer attributes
1117 * which shall not be checked for flag/filter/other internal
1123 test
->state
= TEST_INTERNAL_ERROR
;
1125 str_printf("invalid attribute type: %d", pa
->type
);
1129 /* Attempt to call a custom handler if set for further processing. */
1130 test_custom(test
, pa
, peer
, group
, peer_set
, group_set
);
1133 static void test_peer_attr(struct test
*test
, struct test_peer_attr
*pa
)
1137 const char *ecp
= pa
->o
.invert_peer
? "no " : "";
1138 const char *dcp
= pa
->o
.invert_peer
? "" : "no ";
1139 const char *ecg
= pa
->o
.invert_group
? "no " : "";
1140 const char *dcg
= pa
->o
.invert_group
? "" : "no ";
1141 const char *peer_cmd
= pa
->peer_cmd
?: pa
->cmd
;
1142 const char *group_cmd
= pa
->group_cmd
?: pa
->cmd
;
1143 struct peer
*p
= test
->peer
;
1144 struct peer_group
*g
= test
->group
;
1146 /* Determine type and if test is address-family relevant */
1147 type
= str_from_attr_type(pa
->type
);
1149 test
->state
= TEST_INTERNAL_ERROR
;
1151 str_printf("invalid attribute type: %d", pa
->type
);
1156 * =====================================================================
1157 * Test Case Suite 1: Config persistence after adding peer to group
1159 * Example: If a peer attribute has value [1] and a group attribute has
1160 * value [2], the peer attribute value should be persisted when the peer
1161 * gets added to the peer-group.
1163 * This test suite is meant to test the group2peer functions which can
1164 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1166 * =====================================================================
1169 /* Test Preparation: Switch and activate address-family. */
1170 if (!is_attr_type_global(pa
->type
)) {
1171 test_log(test
, "prepare: switch address-family to [%s]",
1172 afi_safi_print(pa
->afi
, pa
->safi
));
1173 test_execute(test
, "address-family %s %s",
1174 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1175 test_execute(test
, "neighbor %s activate", g
->name
);
1176 test_execute(test
, "neighbor %s activate", p
->host
);
1179 /* Skip peer-group to peer transfer test cases if requested. */
1180 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SUCCESS
)
1181 test
->state
= TEST_SKIPPING
;
1183 /* Test Case: Set flag on BGP peer. */
1184 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1186 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1187 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1188 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1189 test_process(test
, pa
, p
, g
->conf
, true, false);
1191 /* Test Case: Set flag on BGP peer-group. */
1192 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1194 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1195 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1196 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1197 test_process(test
, pa
, p
, g
->conf
, true, true);
1199 /* Test Case: Add BGP peer to peer-group. */
1200 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1202 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1203 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1204 p
->conf_if
? "interface " : "", g
->name
);
1205 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1206 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1207 test_process(test
, pa
, p
, g
->conf
, true, true);
1209 /* Test Case: Unset flag on BGP peer-group. */
1210 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1211 group_cmd
, g
->name
);
1212 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1213 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1214 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1215 test_process(test
, pa
, p
, g
->conf
, true, false);
1218 * =====================================================================
1219 * Test Case Suite 2: Config inheritance after adding peer to group
1221 * Example: If a peer attribute has not been set and a group attribute
1222 * has a value of [2], the group attribute should be inherited to the
1223 * peer without flagging the newly set value as overridden.
1225 * This test suite is meant to test the group2peer functions which can
1226 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1228 * =====================================================================
1231 /* Test Preparation: Re-initialize test environment. */
1232 test_initialize(test
);
1236 /* Test Preparation: Switch and activate address-family. */
1237 if (!is_attr_type_global(pa
->type
)) {
1238 test_log(test
, "prepare: switch address-family to [%s]",
1239 afi_safi_print(pa
->afi
, pa
->safi
));
1240 test_execute(test
, "address-family %s %s",
1241 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1242 test_execute(test
, "neighbor %s activate", g
->name
);
1243 test_execute(test
, "neighbor %s activate", p
->host
);
1246 /* Test Case: Set flag on BGP peer-group. */
1247 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1249 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1250 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1251 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1252 test_process(test
, pa
, p
, g
->conf
, false, true);
1254 /* Test Case: Add BGP peer to peer-group. */
1255 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1257 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1258 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1259 p
->conf_if
? "interface " : "", g
->name
);
1260 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1261 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1262 test_process(test
, pa
, p
, g
->conf
, false, true);
1264 /* Stop skipping test cases if previously enabled. */
1265 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SKIPPING
)
1266 test
->state
= TEST_SUCCESS
;
1269 * =====================================================================
1270 * Test Case Suite 3: Miscellaneous flag checks
1272 * This test suite does not focus on initial peer-group inheritance and
1273 * instead executes various different commands to set/unset attributes
1274 * on both peer- and group-level. These checks should always be executed
1276 * =====================================================================
1279 /* Test Preparation: Re-initialize test environment. */
1280 test_initialize(test
);
1284 /* Test Preparation: Switch and activate address-family. */
1285 if (!is_attr_type_global(pa
->type
)) {
1286 test_log(test
, "prepare: switch address-family to [%s]",
1287 afi_safi_print(pa
->afi
, pa
->safi
));
1288 test_execute(test
, "address-family %s %s",
1289 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1290 test_execute(test
, "neighbor %s activate", g
->name
);
1291 test_execute(test
, "neighbor %s activate", p
->host
);
1294 /* Test Case: Set flag on BGP peer. */
1295 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1297 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
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: Add BGP peer to peer-group. */
1303 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1305 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1306 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1307 p
->conf_if
? "interface " : "", g
->name
);
1308 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1309 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1310 test_process(test
, pa
, p
, g
->conf
, true, false);
1312 /* Test Case: Re-add BGP peer to peer-group. */
1313 test_log(test
, "case %02d: re-add peer [%s] to group [%s]", tc
++,
1315 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1316 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1317 p
->conf_if
? "interface " : "", g
->name
);
1318 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1319 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1320 test_process(test
, pa
, p
, g
->conf
, true, false);
1322 /* Test Case: Set flag on BGP peer-group. */
1323 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1325 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1326 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1327 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1328 test_process(test
, pa
, p
, g
->conf
, true, true);
1330 /* Test Case: Unset flag on BGP peer-group. */
1331 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1332 group_cmd
, g
->name
);
1333 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1334 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1335 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1336 test_process(test
, pa
, p
, g
->conf
, true, false);
1338 /* Test Case: Set flag on BGP peer-group. */
1339 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1341 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1342 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1343 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1344 test_process(test
, pa
, p
, g
->conf
, true, true);
1346 /* Test Case: Re-set flag on BGP peer. */
1347 test_log(test
, "case %02d: re-set %s [%s] on [%s]", tc
++, type
,
1349 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1350 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1351 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1352 test_process(test
, pa
, p
, g
->conf
, true, true);
1354 /* Test Case: Unset flag on BGP peer. */
1355 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1357 test_execute(test
, "%sneighbor %s %s", dcp
, p
->host
, peer_cmd
);
1358 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1359 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1360 test_process(test
, pa
, p
, g
->conf
, false, true);
1362 /* Test Case: Unset flag on BGP peer-group. */
1363 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1364 group_cmd
, g
->name
);
1365 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1366 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1367 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1368 test_process(test
, pa
, p
, g
->conf
, false, false);
1370 /* Test Case: Set flag on BGP peer. */
1371 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1373 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1374 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1375 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1376 test_process(test
, pa
, p
, g
->conf
, true, false);
1379 static void bgp_startup(void)
1382 openzlog("testbgpd", "NONE", 0, LOG_CONS
| LOG_NDELAY
| LOG_PID
,
1384 zprivs_preinit(&bgpd_privs
);
1385 zprivs_init(&bgpd_privs
);
1387 master
= thread_master_create(NULL
);
1388 bgp_master_init(master
);
1389 bgp_option_set(BGP_OPT_NO_LISTEN
);
1390 vrf_init(NULL
, NULL
, NULL
, NULL
);
1395 static void bgp_shutdown(void)
1398 struct listnode
*node
, *nnode
;
1402 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
1406 bgp_route_map_terminate();
1408 bgp_pthreads_finish();
1409 access_list_add_hook(NULL
);
1410 access_list_delete_hook(NULL
);
1411 access_list_reset();
1412 as_list_add_hook(NULL
);
1413 as_list_delete_hook(NULL
);
1415 prefix_list_add_hook(NULL
);
1416 prefix_list_delete_hook(NULL
);
1417 prefix_list_reset();
1418 community_list_terminate(bgp_clist
);
1420 #ifdef ENABLE_BGP_VNC
1421 vnc_zebra_destroy();
1423 bgp_zebra_destroy();
1425 bf_free(bm
->rd_idspace
);
1426 list_delete_and_null(&bm
->bgp
);
1427 memset(bm
, 0, sizeof(*bm
));
1431 zprivs_terminate(&bgpd_privs
);
1432 thread_master_free(master
);
1440 struct list
*pa_list
;
1441 struct test_peer_attr
*pa
, *pac
;
1442 struct listnode
*node
, *nnode
;
1446 pa_list
= list_new();
1448 while (test_peer_attrs
[i
].cmd
) {
1449 pa
= &test_peer_attrs
[i
++];
1451 /* Just copy the peer attribute structure for global flags. */
1452 if (is_attr_type_global(pa
->type
)) {
1453 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1454 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1455 listnode_add(pa_list
, pac
);
1459 /* Fallback to default families if not specified. */
1460 if (!pa
->families
[0].afi
&& !pa
->families
[0].safi
)
1461 memcpy(&pa
->families
, test_default_families
,
1462 sizeof(test_default_families
));
1464 /* Add peer attribute definition for each address family. */
1466 while (pa
->families
[ii
].afi
&& pa
->families
[ii
].safi
) {
1467 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1468 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1470 pac
->afi
= pa
->families
[ii
].afi
;
1471 pac
->safi
= pa
->families
[ii
].safi
;
1472 listnode_add(pa_list
, pac
);
1478 for (ALL_LIST_ELEMENTS(pa_list
, node
, nnode
, pa
)) {
1482 /* Build test description string. */
1483 if (pa
->afi
&& pa
->safi
)
1484 desc
= str_printf("peer\\%s-%s\\%s",
1485 str_from_afi(pa
->afi
),
1486 str_from_safi(pa
->safi
), pa
->cmd
);
1488 desc
= str_printf("peer\\%s", pa
->cmd
);
1490 /* Initialize new test instance. */
1491 test
= test_new(desc
, pa
->o
.use_ibgp
, pa
->o
.use_iface_peer
);
1492 XFREE(MTYPE_TMP
, desc
);
1494 /* Execute tests and finish test instance. */
1495 test_peer_attr(test
, pa
);
1498 /* Print empty line as spacer. */
1501 /* Free memory used for peer-attr declaration. */
1502 XFREE(MTYPE_TMP
, pa
);
1505 list_delete_and_null(&pa_list
);