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"
32 #include "bgpd/bgp_network.h"
33 #include "lib/routing_nb.h"
34 #include "lib/northbound_cli.h"
35 #include "bgpd/bgp_nb.h"
38 #include "bgpd/rfapi/rfapi_backend.h"
41 #define OUT_SYMBOL_INFO "\u25ba"
42 #define OUT_SYMBOL_OK "\u2714"
43 #define OUT_SYMBOL_NOK "\u2716"
45 #define TEST_ASSERT(T, C) \
47 if ((T)->state != TEST_SUCCESS || (C)) \
49 (T)->state = TEST_ASSERT_ERROR; \
50 (T)->error = str_printf("assertion failed: %s (%s:%d)", (#C), \
51 __FILE__, __LINE__); \
54 #define TEST_ASSERT_EQ(T, A, B) \
56 if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
58 (T)->state = TEST_ASSERT_ERROR; \
59 (T)->error = str_printf( \
60 "assertion failed: %s[%d] == [%d]%s (%s:%d)", (#A), \
61 (A), (B), (#B), __FILE__, __LINE__); \
64 #define TEST_HANDLER_MAX 5
65 #define TEST_HANDLER(name) _test_handler_##name
66 #define TEST_HANDLER_DECL(name) \
67 static void _test_handler_##name( \
68 struct test *test, struct test_peer_attr *pa, \
69 struct peer *peer, struct peer *group, bool peer_set, \
72 #define TEST_ATTR_HANDLER_DECL(name, attr, pval, gval) \
73 TEST_HANDLER_DECL(name) \
76 TEST_ASSERT_EQ(test, peer->attr, (pval)); \
77 else if (peer_group_active(peer) && group_set) \
78 TEST_ASSERT_EQ(test, peer->attr, (gval)); \
80 TEST_ASSERT_EQ(test, group->attr, (gval)); \
82 TEST_HANDLER_DECL(name)
84 #define TEST_STR_ATTR_HANDLER_DECL(name, attr, pval, gval) \
85 TEST_HANDLER_DECL(name) \
88 TEST_ASSERT(test, peer->attr != NULL); \
89 TEST_ASSERT(test, !strcmp(peer->attr, (pval))); \
90 } else if (peer_group_active(peer) && group_set) { \
91 TEST_ASSERT(test, peer->attr != NULL); \
92 TEST_ASSERT(test, !strcmp(peer->attr, (gval))); \
95 TEST_ASSERT(test, group->attr != NULL); \
96 TEST_ASSERT(test, !strcmp(group->attr, (gval))); \
99 TEST_HANDLER_DECL(name)
101 #define TEST_SU_ATTR_HANDLER_DECL(name, attr, pval, gval) \
102 TEST_HANDLER_DECL(name) \
104 union sockunion su; \
106 str2sockunion(pval, &su); \
107 TEST_ASSERT(test, !sockunion_cmp(peer->attr, &su)); \
108 } else if (peer_group_active(peer) && group_set) { \
109 str2sockunion(gval, &su); \
110 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
113 str2sockunion(gval, &su); \
114 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
117 TEST_HANDLER_DECL(name)
119 /* Required variables to link in libbgp */
120 struct zebra_privs_t bgpd_privs
= {0};
121 struct thread_master
*master
;
133 enum test_peer_attr_type
{
135 PEER_AT_AF_FILTER
= 1,
136 PEER_AT_AF_CUSTOM
= 2,
137 PEER_AT_GLOBAL_FLAG
= 3,
138 PEER_AT_GLOBAL_CUSTOM
= 4
142 enum test_state state
;
150 struct peer_group
*group
;
161 const char *peer_address
;
162 const char *peer_interface
;
163 const char *peer_group
;
166 struct test_peer_family
{
171 struct test_peer_attr
{
173 const char *peer_cmd
;
174 const char *group_cmd
;
176 enum test_peer_attr_type type
;
189 bool skip_xfer_cases
;
194 struct test_peer_family families
[AFI_MAX
* SAFI_MAX
];
196 void (*handlers
[TEST_HANDLER_MAX
])(struct test
*test
,
197 struct test_peer_attr
*pa
,
199 struct peer
*group
, bool peer_set
,
203 static struct test_config cfg
= {
206 .peer_address
= "1.1.1.1",
207 .peer_interface
= "IP-TEST",
208 .peer_group
= "PG-TEST",
211 static struct test_peer_family test_default_families
[] = {
212 {.afi
= AFI_IP
, .safi
= SAFI_UNICAST
},
213 {.afi
= AFI_IP
, .safi
= SAFI_MULTICAST
},
214 {.afi
= AFI_IP6
, .safi
= SAFI_UNICAST
},
215 {.afi
= AFI_IP6
, .safi
= SAFI_MULTICAST
},
218 static char *str_vprintf(const char *fmt
, va_list ap
)
227 ret
= vsnprintf(buf
, buf_size
, fmt
, apc
);
230 if (ret
>= 0 && ret
< buf_size
)
238 buf
= XREALLOC(MTYPE_TMP
, buf
, buf_size
);
244 static char *str_printf(const char *fmt
, ...)
250 buf
= str_vprintf(fmt
, ap
);
256 TEST_ATTR_HANDLER_DECL(advertisement_interval
, v_routeadv
, 10, 20);
257 TEST_STR_ATTR_HANDLER_DECL(password
, password
, "FRR-Peer", "FRR-Group");
258 TEST_ATTR_HANDLER_DECL(local_as
, change_local_as
, 1, 2);
259 TEST_ATTR_HANDLER_DECL(timers_1
, keepalive
, 10, 20);
260 TEST_ATTR_HANDLER_DECL(timers_2
, holdtime
, 30, 60);
261 TEST_ATTR_HANDLER_DECL(addpath_types
, addpath_type
[pa
->afi
][pa
->safi
],
262 BGP_ADDPATH_ALL
, BGP_ADDPATH_BEST_PER_AS
);
263 TEST_SU_ATTR_HANDLER_DECL(update_source_su
, update_source
, "255.255.255.1",
265 TEST_STR_ATTR_HANDLER_DECL(update_source_if
, update_if
, "IF-PEER", "IF-GROUP");
267 TEST_ATTR_HANDLER_DECL(allowas_in
, allowas_in
[pa
->afi
][pa
->safi
], 1, 2);
268 TEST_STR_ATTR_HANDLER_DECL(default_originate_route_map
,
269 default_rmap
[pa
->afi
][pa
->safi
].name
, "RM-PEER",
271 TEST_STR_ATTR_HANDLER_DECL(
273 filter
[pa
->afi
][pa
->safi
].dlist
[pa
->u
.filter
.direct
].name
, "DL-PEER",
275 TEST_STR_ATTR_HANDLER_DECL(
276 filter_list
, filter
[pa
->afi
][pa
->safi
].aslist
[pa
->u
.filter
.direct
].name
,
277 "FL-PEER", "FL-GROUP");
278 TEST_ATTR_HANDLER_DECL(maximum_prefix
, pmax
[pa
->afi
][pa
->safi
], 10, 20);
279 TEST_ATTR_HANDLER_DECL(maximum_prefix_threshold
,
280 pmax_threshold
[pa
->afi
][pa
->safi
], 1, 2);
281 TEST_ATTR_HANDLER_DECL(maximum_prefix_restart
, pmax_restart
[pa
->afi
][pa
->safi
],
283 TEST_STR_ATTR_HANDLER_DECL(
284 prefix_list
, filter
[pa
->afi
][pa
->safi
].plist
[pa
->u
.filter
.direct
].name
,
285 "PL-PEER", "PL-GROUP");
286 TEST_STR_ATTR_HANDLER_DECL(
287 route_map
, filter
[pa
->afi
][pa
->safi
].map
[pa
->u
.filter
.direct
].name
,
288 "RM-PEER", "RM-GROUP");
289 TEST_STR_ATTR_HANDLER_DECL(unsuppress_map
, filter
[pa
->afi
][pa
->safi
].usmap
.name
,
290 "UM-PEER", "UM-GROUP");
291 TEST_ATTR_HANDLER_DECL(weight
, weight
[pa
->afi
][pa
->safi
], 100, 200);
293 /* clang-format off */
294 static struct test_peer_attr test_peer_attrs
[] = {
295 /* Peer Attributes */
297 .cmd
= "advertisement-interval",
298 .peer_cmd
= "advertisement-interval 10",
299 .group_cmd
= "advertisement-interval 20",
300 .u
.flag
= PEER_FLAG_ROUTEADV
,
301 .type
= PEER_AT_GLOBAL_FLAG
,
302 .handlers
[0] = TEST_HANDLER(advertisement_interval
),
305 .cmd
= "capability dynamic",
306 .u
.flag
= PEER_FLAG_DYNAMIC_CAPABILITY
,
307 .type
= PEER_AT_GLOBAL_FLAG
,
310 .cmd
= "capability extended-nexthop",
311 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
312 .type
= PEER_AT_GLOBAL_FLAG
,
315 .cmd
= "capability extended-nexthop",
316 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
317 .type
= PEER_AT_GLOBAL_FLAG
,
318 .o
.invert_peer
= true,
319 .o
.use_iface_peer
= true,
322 .cmd
= "description",
323 .peer_cmd
= "description FRR Peer",
324 .group_cmd
= "description FRR Group",
325 .type
= PEER_AT_GLOBAL_CUSTOM
,
328 .cmd
= "disable-connected-check",
329 .u
.flag
= PEER_FLAG_DISABLE_CONNECTED_CHECK
,
330 .type
= PEER_AT_GLOBAL_FLAG
,
333 .cmd
= "dont-capability-negotiate",
334 .u
.flag
= PEER_FLAG_DONT_CAPABILITY
,
335 .type
= PEER_AT_GLOBAL_FLAG
,
338 .cmd
= "enforce-first-as",
339 .u
.flag
= PEER_FLAG_ENFORCE_FIRST_AS
,
340 .type
= PEER_AT_GLOBAL_FLAG
,
344 .peer_cmd
= "local-as 1",
345 .group_cmd
= "local-as 2",
346 .u
.flag
= PEER_FLAG_LOCAL_AS
,
347 .type
= PEER_AT_GLOBAL_FLAG
,
348 .handlers
[0] = TEST_HANDLER(local_as
),
351 .cmd
= "local-as 1 no-prepend",
352 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_NO_PREPEND
,
353 .type
= PEER_AT_GLOBAL_FLAG
,
356 .cmd
= "local-as 1 no-prepend replace-as",
357 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_REPLACE_AS
,
358 .type
= PEER_AT_GLOBAL_FLAG
,
361 .cmd
= "override-capability",
362 .u
.flag
= PEER_FLAG_OVERRIDE_CAPABILITY
,
363 .type
= PEER_AT_GLOBAL_FLAG
,
367 .u
.flag
= PEER_FLAG_PASSIVE
,
368 .type
= PEER_AT_GLOBAL_FLAG
,
372 .peer_cmd
= "password FRR-Peer",
373 .group_cmd
= "password FRR-Group",
374 .u
.flag
= PEER_FLAG_PASSWORD
,
375 .type
= PEER_AT_GLOBAL_FLAG
,
376 .handlers
[0] = TEST_HANDLER(password
),
380 .u
.flag
= PEER_FLAG_SHUTDOWN
,
381 .type
= PEER_AT_GLOBAL_FLAG
,
384 .cmd
= "strict-capability-match",
385 .u
.flag
= PEER_FLAG_STRICT_CAP_MATCH
,
386 .type
= PEER_AT_GLOBAL_FLAG
,
390 .peer_cmd
= "timers 10 30",
391 .group_cmd
= "timers 20 60",
392 .u
.flag
= PEER_FLAG_TIMER
,
393 .type
= PEER_AT_GLOBAL_FLAG
,
394 .handlers
[0] = TEST_HANDLER(timers_1
),
395 .handlers
[1] = TEST_HANDLER(timers_2
),
398 .cmd
= "timers connect",
399 .peer_cmd
= "timers connect 10",
400 .group_cmd
= "timers connect 20",
401 .u
.flag
= PEER_FLAG_TIMER_CONNECT
,
402 .type
= PEER_AT_GLOBAL_FLAG
,
405 .cmd
= "update-source",
406 .peer_cmd
= "update-source 255.255.255.1",
407 .group_cmd
= "update-source 255.255.255.2",
408 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
409 .type
= PEER_AT_GLOBAL_FLAG
,
410 .handlers
[0] = TEST_HANDLER(update_source_su
),
413 .cmd
= "update-source",
414 .peer_cmd
= "update-source IF-PEER",
415 .group_cmd
= "update-source IF-GROUP",
416 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
417 .type
= PEER_AT_GLOBAL_FLAG
,
418 .handlers
[0] = TEST_HANDLER(update_source_if
),
421 /* Address Family Attributes */
424 .peer_cmd
= "addpath-tx-all-paths",
425 .group_cmd
= "addpath-tx-bestpath-per-AS",
426 .type
= PEER_AT_AF_CUSTOM
,
427 .handlers
[0] = TEST_HANDLER(addpath_types
),
431 .peer_cmd
= "allowas-in 1",
432 .group_cmd
= "allowas-in 2",
433 .u
.flag
= PEER_FLAG_ALLOWAS_IN
,
434 .handlers
[0] = TEST_HANDLER(allowas_in
),
437 .cmd
= "allowas-in origin",
438 .u
.flag
= PEER_FLAG_ALLOWAS_IN_ORIGIN
,
441 .cmd
= "as-override",
442 .u
.flag
= PEER_FLAG_AS_OVERRIDE
,
445 .cmd
= "attribute-unchanged as-path",
446 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
,
449 .cmd
= "attribute-unchanged next-hop",
450 .u
.flag
= PEER_FLAG_NEXTHOP_UNCHANGED
,
453 .cmd
= "attribute-unchanged med",
454 .u
.flag
= PEER_FLAG_MED_UNCHANGED
,
457 .cmd
= "attribute-unchanged as-path next-hop",
458 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
459 | PEER_FLAG_NEXTHOP_UNCHANGED
,
462 .cmd
= "attribute-unchanged as-path med",
463 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
464 | PEER_FLAG_MED_UNCHANGED
,
467 .cmd
= "attribute-unchanged as-path next-hop med",
468 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
469 | PEER_FLAG_NEXTHOP_UNCHANGED
470 | PEER_FLAG_MED_UNCHANGED
,
473 .cmd
= "capability orf prefix-list send",
474 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
,
477 .cmd
= "capability orf prefix-list receive",
478 .u
.flag
= PEER_FLAG_ORF_PREFIX_RM
,
481 .cmd
= "capability orf prefix-list both",
482 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
| PEER_FLAG_ORF_PREFIX_RM
,
485 .cmd
= "default-originate",
486 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
489 .cmd
= "default-originate route-map",
490 .peer_cmd
= "default-originate route-map RM-PEER",
491 .group_cmd
= "default-originate route-map RM-GROUP",
492 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
493 .handlers
[0] = TEST_HANDLER(default_originate_route_map
),
496 .cmd
= "distribute-list",
497 .peer_cmd
= "distribute-list DL-PEER in",
498 .group_cmd
= "distribute-list DL-GROUP in",
499 .type
= PEER_AT_AF_FILTER
,
500 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
501 .u
.filter
.direct
= FILTER_IN
,
502 .handlers
[0] = TEST_HANDLER(distribute_list
),
505 .cmd
= "distribute-list",
506 .peer_cmd
= "distribute-list DL-PEER out",
507 .group_cmd
= "distribute-list DL-GROUP out",
508 .type
= PEER_AT_AF_FILTER
,
509 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
510 .u
.filter
.direct
= FILTER_OUT
,
511 .handlers
[0] = TEST_HANDLER(distribute_list
),
514 .cmd
= "filter-list",
515 .peer_cmd
= "filter-list FL-PEER in",
516 .group_cmd
= "filter-list FL-GROUP in",
517 .type
= PEER_AT_AF_FILTER
,
518 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
519 .u
.filter
.direct
= FILTER_IN
,
520 .handlers
[0] = TEST_HANDLER(filter_list
),
523 .cmd
= "filter-list",
524 .peer_cmd
= "filter-list FL-PEER out",
525 .group_cmd
= "filter-list FL-GROUP out",
526 .type
= PEER_AT_AF_FILTER
,
527 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
528 .u
.filter
.direct
= FILTER_OUT
,
529 .handlers
[0] = TEST_HANDLER(filter_list
),
532 .cmd
= "maximum-prefix",
533 .peer_cmd
= "maximum-prefix 10",
534 .group_cmd
= "maximum-prefix 20",
535 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
536 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
539 .cmd
= "maximum-prefix",
540 .peer_cmd
= "maximum-prefix 10 restart 100",
541 .group_cmd
= "maximum-prefix 20 restart 200",
542 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
543 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
544 .handlers
[1] = TEST_HANDLER(maximum_prefix_restart
),
547 .cmd
= "maximum-prefix",
548 .peer_cmd
= "maximum-prefix 10 1 restart 100",
549 .group_cmd
= "maximum-prefix 20 2 restart 200",
550 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
551 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
552 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
553 .handlers
[2] = TEST_HANDLER(maximum_prefix_restart
),
556 .cmd
= "maximum-prefix",
557 .peer_cmd
= "maximum-prefix 10 warning-only",
558 .group_cmd
= "maximum-prefix 20 warning-only",
559 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
560 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
563 .cmd
= "maximum-prefix",
564 .peer_cmd
= "maximum-prefix 10 1 warning-only",
565 .group_cmd
= "maximum-prefix 20 2 warning-only",
566 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
567 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
568 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
571 .cmd
= "next-hop-self",
572 .u
.flag
= PEER_FLAG_NEXTHOP_SELF
,
575 .cmd
= "next-hop-self force",
576 .u
.flag
= PEER_FLAG_FORCE_NEXTHOP_SELF
,
579 .cmd
= "prefix-list",
580 .peer_cmd
= "prefix-list PL-PEER in",
581 .group_cmd
= "prefix-list PL-GROUP in",
582 .type
= PEER_AT_AF_FILTER
,
583 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
584 .u
.filter
.direct
= FILTER_IN
,
585 .handlers
[0] = TEST_HANDLER(prefix_list
),
588 .cmd
= "prefix-list",
589 .peer_cmd
= "prefix-list PL-PEER out",
590 .group_cmd
= "prefix-list PL-GROUP out",
591 .type
= PEER_AT_AF_FILTER
,
592 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
593 .u
.filter
.direct
= FILTER_OUT
,
594 .handlers
[0] = TEST_HANDLER(prefix_list
),
597 .cmd
= "remove-private-AS",
598 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
,
601 .cmd
= "remove-private-AS all",
602 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
603 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL
,
606 .cmd
= "remove-private-AS replace-AS",
607 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
608 | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
,
611 .cmd
= "remove-private-AS all replace-AS",
612 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
,
616 .peer_cmd
= "route-map RM-PEER in",
617 .group_cmd
= "route-map RM-GROUP in",
618 .type
= PEER_AT_AF_FILTER
,
619 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
620 .u
.filter
.direct
= FILTER_IN
,
621 .handlers
[0] = TEST_HANDLER(route_map
),
625 .peer_cmd
= "route-map RM-PEER out",
626 .group_cmd
= "route-map RM-GROUP out",
627 .type
= PEER_AT_AF_FILTER
,
628 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
629 .u
.filter
.direct
= FILTER_OUT
,
630 .handlers
[0] = TEST_HANDLER(route_map
),
633 .cmd
= "route-reflector-client",
634 .u
.flag
= PEER_FLAG_REFLECTOR_CLIENT
,
636 .o
.skip_xfer_cases
= true,
639 .cmd
= "route-server-client",
640 .u
.flag
= PEER_FLAG_RSERVER_CLIENT
,
643 .cmd
= "send-community",
644 .u
.flag
= PEER_FLAG_SEND_COMMUNITY
,
645 .o
.invert_peer
= true,
646 .o
.invert_group
= true,
649 .cmd
= "send-community extended",
650 .u
.flag
= PEER_FLAG_SEND_EXT_COMMUNITY
,
651 .o
.invert_peer
= true,
652 .o
.invert_group
= true,
655 .cmd
= "send-community large",
656 .u
.flag
= PEER_FLAG_SEND_LARGE_COMMUNITY
,
657 .o
.invert_peer
= true,
658 .o
.invert_group
= true,
661 .cmd
= "soft-reconfiguration inbound",
662 .u
.flag
= PEER_FLAG_SOFT_RECONFIG
,
665 .cmd
= "unsuppress-map",
666 .peer_cmd
= "unsuppress-map UM-PEER",
667 .group_cmd
= "unsuppress-map UM-GROUP",
668 .type
= PEER_AT_AF_FILTER
,
669 .u
.filter
.flag
= PEER_FT_UNSUPPRESS_MAP
,
670 .u
.filter
.direct
= 0,
671 .handlers
[0] = TEST_HANDLER(unsuppress_map
),
675 .peer_cmd
= "weight 100",
676 .group_cmd
= "weight 200",
677 .u
.flag
= PEER_FLAG_WEIGHT
,
678 .handlers
[0] = TEST_HANDLER(weight
),
682 /* clang-format on */
684 static const char *str_from_afi(afi_t afi
)
692 return "<unknown AFI>";
696 static const char *str_from_safi(safi_t safi
)
704 return "<unknown SAFI>";
708 static const char *str_from_attr_type(enum test_peer_attr_type at
)
711 case PEER_AT_GLOBAL_FLAG
:
713 case PEER_AT_AF_FLAG
:
715 case PEER_AT_AF_FILTER
:
717 case PEER_AT_GLOBAL_CUSTOM
:
718 case PEER_AT_AF_CUSTOM
:
725 static bool is_attr_type_global(enum test_peer_attr_type at
)
727 return at
== PEER_AT_GLOBAL_FLAG
|| at
== PEER_AT_GLOBAL_CUSTOM
;
730 static void test_log(struct test
*test
, const char *fmt
, ...)
734 /* Skip logging if test instance has previously failed. */
735 if (test
->state
!= TEST_SUCCESS
)
738 /* Store formatted log message. */
740 listnode_add(test
->log
, str_vprintf(fmt
, ap
));
744 static void test_execute(struct test
*test
, const char *fmt
, ...)
751 /* Skip execution if test instance has previously failed. */
752 if (test
->state
!= TEST_SUCCESS
)
755 /* Format command string with variadic arguments. */
757 cmd
= str_vprintf(fmt
, ap
);
760 test
->state
= TEST_INTERNAL_ERROR
;
762 str_printf("could not format command string [%s]", fmt
);
766 /* Tokenize formatted command string. */
767 vline
= cmd_make_strvec(cmd
);
769 test
->state
= TEST_INTERNAL_ERROR
;
770 test
->error
= str_printf(
771 "tokenizing command string [%s] returned empty result",
773 XFREE(MTYPE_TMP
, cmd
);
778 /* Execute command (non-strict). */
779 ret
= cmd_execute_command(vline
, test
->vty
, NULL
, 0);
780 if (ret
== CMD_SUCCESS
) {
781 /* Commit any pending changes, irnore error */
782 ret
= nb_cli_pending_commit_check(test
->vty
);
784 if (ret
!= CMD_SUCCESS
) {
785 test
->state
= TEST_COMMAND_ERROR
;
786 test
->error
= str_printf(
787 "execution of command [%s] has failed with code [%d]",
792 cmd_free_strvec(vline
);
793 XFREE(MTYPE_TMP
, cmd
);
796 static void test_config(struct test
*test
, const char *fmt
, bool invert
,
804 /* Skip execution if test instance has previously failed. */
805 if (test
->state
!= TEST_SUCCESS
)
808 /* Format matcher string with variadic arguments. */
810 matcher
= str_vprintf(fmt
, apc
);
813 test
->state
= TEST_INTERNAL_ERROR
;
815 str_printf("could not format matcher string [%s]", fmt
);
819 /* Fetch BGP configuration into buffer. */
820 bgp_config_write(test
->vty
);
821 config
= buffer_getstr(test
->vty
->obuf
);
822 buffer_reset(test
->vty
->obuf
);
824 /* Match config against matcher. */
825 matched
= !!strstr(config
, matcher
);
826 if (!matched
&& !invert
) {
827 test
->state
= TEST_CONFIG_ERROR
;
828 test
->error
= str_printf("expected config [%s] to be present",
830 } else if (matched
&& invert
) {
831 test
->state
= TEST_CONFIG_ERROR
;
832 test
->error
= str_printf("expected config [%s] to be absent",
836 /* Free memory and return. */
837 XFREE(MTYPE_TMP
, matcher
);
838 XFREE(MTYPE_TMP
, config
);
841 static void test_config_present(struct test
*test
, const char *fmt
, ...)
846 test_config(test
, fmt
, false, ap
);
850 static void test_config_absent(struct test
*test
, const char *fmt
, ...)
855 test_config(test
, fmt
, true, ap
);
859 static void test_initialize(struct test
*test
)
863 /* Skip execution if test instance has previously failed. */
864 if (test
->state
!= TEST_SUCCESS
)
867 /* Log message about (re)-initialization */
868 test_log(test
, "prepare: %sinitialize bgp test environment",
869 test
->bgp
? "re-" : "");
871 /* Attempt gracefully to purge previous BGP configuration. */
872 test_execute(test
, "no router bgp");
873 test
->state
= TEST_SUCCESS
;
875 /* Initialize BGP test environment. */
876 test_execute(test
, "router bgp %d", cfg
.local_asn
);
877 test_execute(test
, "no bgp default ipv4-unicast");
878 test_execute(test
, "neighbor %s peer-group", cfg
.peer_group
);
879 if (test
->o
.use_iface_peer
) {
880 test_execute(test
, "neighbor %s interface", cfg
.peer_interface
);
881 test_execute(test
, "neighbor %s remote-as %d",
883 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
885 test_execute(test
, "neighbor %s remote-as %d", cfg
.peer_address
,
886 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
889 if (test
->state
!= TEST_SUCCESS
)
892 /* Fetch default BGP instance. */
893 test
->bgp
= bgp_get_default();
895 test
->state
= TEST_INTERNAL_ERROR
;
897 str_printf("could not retrieve default bgp instance");
901 /* Fetch peer instance. */
902 if (test
->o
.use_iface_peer
) {
904 peer_lookup_by_conf_if(test
->bgp
, cfg
.peer_interface
);
906 str2sockunion(cfg
.peer_address
, &su
);
907 test
->peer
= peer_lookup(test
->bgp
, &su
);
910 test
->state
= TEST_INTERNAL_ERROR
;
911 test
->error
= str_printf(
912 "could not retrieve instance of bgp peer [%s]",
917 /* Fetch peer-group instance. */
918 test
->group
= peer_group_lookup(test
->bgp
, cfg
.peer_group
);
920 test
->state
= TEST_INTERNAL_ERROR
;
921 test
->error
= str_printf(
922 "could not retrieve instance of bgp peer-group [%s]",
928 static struct test
*test_new(const char *desc
, bool use_ibgp
,
933 test
= XCALLOC(MTYPE_TMP
, sizeof(struct test
));
934 test
->state
= TEST_SUCCESS
;
935 test
->desc
= XSTRDUP(MTYPE_TMP
, desc
);
936 test
->log
= list_new();
937 test
->o
.use_ibgp
= use_ibgp
;
938 test
->o
.use_iface_peer
= use_iface_peer
;
940 test
->vty
= vty_new();
941 test
->vty
->type
= VTY_TERM
;
942 vty_config_enter(test
->vty
, true, false);
944 test_initialize(test
);
949 static void test_finish(struct test
*test
)
952 struct listnode
*node
, *nnode
;
954 /* Print test output header. */
955 printf("%s [test] %s\n",
956 (test
->state
== TEST_SUCCESS
) ? OUT_SYMBOL_OK
: OUT_SYMBOL_NOK
,
959 /* Print test log messages. */
960 for (ALL_LIST_ELEMENTS(test
->log
, node
, nnode
, msg
)) {
961 printf("%s %s\n", OUT_SYMBOL_INFO
, msg
);
962 XFREE(MTYPE_TMP
, msg
);
965 /* Print test error message if available. */
966 if (test
->state
!= TEST_SUCCESS
&& test
->error
)
967 printf("%s error: %s\n", OUT_SYMBOL_INFO
, test
->error
);
969 /* Print machine-readable result of test. */
970 printf("%s\n", test
->state
== TEST_SUCCESS
? "OK" : "failed");
972 /* Cleanup allocated memory. */
974 vty_close(test
->vty
);
978 list_delete(&test
->log
);
980 XFREE(MTYPE_TMP
, test
->desc
);
982 XFREE(MTYPE_TMP
, test
->error
);
983 XFREE(MTYPE_TMP
, test
);
986 static void test_peer_flags(struct test
*test
, struct test_peer_attr
*pa
,
987 struct peer
*peer
, bool exp_val
, bool exp_ovrd
)
989 bool exp_inv
, cur_val
, cur_ovrd
, cur_inv
;
991 /* Skip execution if test instance has previously failed. */
992 if (test
->state
!= TEST_SUCCESS
)
995 /* Detect if flag is meant to be inverted. */
996 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
997 exp_inv
= pa
->o
.invert_group
;
999 exp_inv
= pa
->o
.invert_peer
;
1001 /* Flip expected value if flag is inverted. */
1004 /* Fetch current state of value, override and invert flags. */
1005 if (pa
->type
== PEER_AT_GLOBAL_FLAG
) {
1006 cur_val
= !!CHECK_FLAG(peer
->flags
, pa
->u
.flag
);
1007 cur_ovrd
= !!CHECK_FLAG(peer
->flags_override
, pa
->u
.flag
);
1008 cur_inv
= !!CHECK_FLAG(peer
->flags_invert
, pa
->u
.flag
);
1009 } else /* if (pa->type == PEER_AT_AF_FLAG) */ {
1010 cur_val
= !!CHECK_FLAG(peer
->af_flags
[pa
->afi
][pa
->safi
],
1012 cur_ovrd
= !!CHECK_FLAG(
1013 peer
->af_flags_override
[pa
->afi
][pa
->safi
], pa
->u
.flag
);
1014 cur_inv
= !!CHECK_FLAG(peer
->af_flags_invert
[pa
->afi
][pa
->safi
],
1018 /* Assert expected flag states. */
1019 TEST_ASSERT_EQ(test
, cur_val
, exp_val
);
1020 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1021 TEST_ASSERT_EQ(test
, cur_inv
, exp_inv
);
1024 static void test_af_filter(struct test
*test
, struct test_peer_attr
*pa
,
1025 struct peer
*peer
, bool exp_state
, bool exp_ovrd
)
1028 struct bgp_filter
*filter
;
1030 /* Skip execution if test instance has previously failed. */
1031 if (test
->state
!= TEST_SUCCESS
)
1034 /* Fetch and assert current state of override flag. */
1035 cur_ovrd
= !!CHECK_FLAG(
1036 peer
->filter_override
[pa
->afi
][pa
->safi
][pa
->u
.filter
.direct
],
1039 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1041 /* Assert that map/list matches expected state (set/unset). */
1042 filter
= &peer
->filter
[pa
->afi
][pa
->safi
];
1044 switch (pa
->u
.filter
.flag
) {
1045 case PEER_FT_DISTRIBUTE_LIST
:
1046 TEST_ASSERT_EQ(test
,
1047 !!(filter
->dlist
[pa
->u
.filter
.direct
].name
),
1050 case PEER_FT_FILTER_LIST
:
1051 TEST_ASSERT_EQ(test
,
1052 !!(filter
->aslist
[pa
->u
.filter
.direct
].name
),
1055 case PEER_FT_PREFIX_LIST
:
1056 TEST_ASSERT_EQ(test
,
1057 !!(filter
->plist
[pa
->u
.filter
.direct
].name
),
1060 case PEER_FT_ROUTE_MAP
:
1061 TEST_ASSERT_EQ(test
, !!(filter
->map
[pa
->u
.filter
.direct
].name
),
1064 case PEER_FT_UNSUPPRESS_MAP
:
1065 TEST_ASSERT_EQ(test
, !!(filter
->usmap
.name
), exp_state
);
1070 static void test_custom(struct test
*test
, struct test_peer_attr
*pa
,
1071 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1075 char *handler_error
;
1077 for (i
= 0; i
< TEST_HANDLER_MAX
; i
++) {
1078 /* Skip execution if test instance has previously failed. */
1079 if (test
->state
!= TEST_SUCCESS
)
1082 /* Skip further execution if handler is undefined. */
1083 if (!pa
->handlers
[i
])
1086 /* Execute custom handler. */
1087 pa
->handlers
[i
](test
, pa
, peer
, group
, peer_set
, group_set
);
1088 if (test
->state
!= TEST_SUCCESS
) {
1089 test
->state
= TEST_CUSTOM_ERROR
;
1090 handler_error
= test
->error
;
1091 test
->error
= str_printf("custom handler failed: %s",
1093 XFREE(MTYPE_TMP
, handler_error
);
1099 static void test_process(struct test
*test
, struct test_peer_attr
*pa
,
1100 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1104 case PEER_AT_GLOBAL_FLAG
:
1105 case PEER_AT_AF_FLAG
:
1108 peer_set
|| (peer_group_active(peer
) && group_set
),
1110 test_peer_flags(test
, pa
, group
, group_set
, false);
1113 case PEER_AT_AF_FILTER
:
1116 peer_set
|| (peer_group_active(peer
) && group_set
),
1118 test_af_filter(test
, pa
, group
, group_set
, false);
1121 case PEER_AT_GLOBAL_CUSTOM
:
1122 case PEER_AT_AF_CUSTOM
:
1124 * Do nothing here - a custom handler can be executed, but this
1125 * is not required. This will allow defining peer attributes
1126 * which shall not be checked for flag/filter/other internal
1132 test
->state
= TEST_INTERNAL_ERROR
;
1134 str_printf("invalid attribute type: %d", pa
->type
);
1138 /* Attempt to call a custom handler if set for further processing. */
1139 test_custom(test
, pa
, peer
, group
, peer_set
, group_set
);
1142 static void test_peer_attr(struct test
*test
, struct test_peer_attr
*pa
)
1146 const char *ecp
= pa
->o
.invert_peer
? "no " : "";
1147 const char *dcp
= pa
->o
.invert_peer
? "" : "no ";
1148 const char *ecg
= pa
->o
.invert_group
? "no " : "";
1149 const char *dcg
= pa
->o
.invert_group
? "" : "no ";
1150 const char *peer_cmd
= pa
->peer_cmd
?: pa
->cmd
;
1151 const char *group_cmd
= pa
->group_cmd
?: pa
->cmd
;
1152 struct peer
*p
= test
->peer
;
1153 struct peer_group
*g
= test
->group
;
1155 /* Determine type and if test is address-family relevant */
1156 type
= str_from_attr_type(pa
->type
);
1158 test
->state
= TEST_INTERNAL_ERROR
;
1160 str_printf("invalid attribute type: %d", pa
->type
);
1165 * =====================================================================
1166 * Test Case Suite 1: Config persistence after adding peer to group
1168 * Example: If a peer attribute has value [1] and a group attribute has
1169 * value [2], the peer attribute value should be persisted when the peer
1170 * gets added to the peer-group.
1172 * This test suite is meant to test the group2peer functions which can
1173 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1175 * =====================================================================
1178 /* Test Preparation: Switch and activate address-family. */
1179 if (!is_attr_type_global(pa
->type
)) {
1180 test_log(test
, "prepare: switch address-family to [%s]",
1181 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1182 test_execute(test
, "address-family %s %s",
1183 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1184 test_execute(test
, "neighbor %s activate", g
->name
);
1185 test_execute(test
, "neighbor %s activate", p
->host
);
1188 /* Skip peer-group to peer transfer test cases if requested. */
1189 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SUCCESS
)
1190 test
->state
= TEST_SKIPPING
;
1192 /* Test Case: Set flag on BGP peer. */
1193 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1195 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1196 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1197 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1198 test_process(test
, pa
, p
, g
->conf
, true, false);
1200 /* Test Case: Set flag on BGP peer-group. */
1201 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1203 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1204 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1205 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1206 test_process(test
, pa
, p
, g
->conf
, true, true);
1208 /* Test Case: Add BGP peer to peer-group. */
1209 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1211 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1212 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1213 p
->conf_if
? "interface " : "", g
->name
);
1214 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1215 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1216 test_process(test
, pa
, p
, g
->conf
, true, true);
1218 /* Test Case: Unset flag on BGP peer-group. */
1219 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1220 group_cmd
, g
->name
);
1221 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1222 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1223 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1224 test_process(test
, pa
, p
, g
->conf
, true, false);
1227 * =====================================================================
1228 * Test Case Suite 2: Config inheritance after adding peer to group
1230 * Example: If a peer attribute has not been set and a group attribute
1231 * has a value of [2], the group attribute should be inherited to the
1232 * peer without flagging the newly set value as overridden.
1234 * This test suite is meant to test the group2peer functions which can
1235 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1237 * =====================================================================
1240 /* Test Preparation: Re-initialize test environment. */
1241 test_initialize(test
);
1245 /* Test Preparation: Switch and activate address-family. */
1246 if (!is_attr_type_global(pa
->type
)) {
1247 test_log(test
, "prepare: switch address-family to [%s]",
1248 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1249 test_execute(test
, "address-family %s %s",
1250 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1251 test_execute(test
, "neighbor %s activate", g
->name
);
1252 test_execute(test
, "neighbor %s activate", p
->host
);
1255 /* Test Case: Set flag on BGP peer-group. */
1256 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1258 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1259 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1260 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1261 test_process(test
, pa
, p
, g
->conf
, false, true);
1263 /* Test Case: Add BGP peer to peer-group. */
1264 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1266 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1267 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1268 p
->conf_if
? "interface " : "", g
->name
);
1269 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1270 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1271 test_process(test
, pa
, p
, g
->conf
, false, true);
1273 /* Stop skipping test cases if previously enabled. */
1274 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SKIPPING
)
1275 test
->state
= TEST_SUCCESS
;
1278 * =====================================================================
1279 * Test Case Suite 3: Miscellaneous flag checks
1281 * This test suite does not focus on initial peer-group inheritance and
1282 * instead executes various different commands to set/unset attributes
1283 * on both peer- and group-level. These checks should always be executed
1285 * =====================================================================
1288 /* Test Preparation: Re-initialize test environment. */
1289 test_initialize(test
);
1293 /* Test Preparation: Switch and activate address-family. */
1294 if (!is_attr_type_global(pa
->type
)) {
1295 test_log(test
, "prepare: switch address-family to [%s]",
1296 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1297 test_execute(test
, "address-family %s %s",
1298 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1299 test_execute(test
, "neighbor %s activate", g
->name
);
1300 test_execute(test
, "neighbor %s activate", p
->host
);
1303 /* Test Case: Set flag on BGP peer. */
1304 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1306 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1307 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1308 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1309 test_process(test
, pa
, p
, g
->conf
, true, false);
1311 /* Test Case: Add BGP peer to peer-group. */
1312 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1314 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1315 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1316 p
->conf_if
? "interface " : "", g
->name
);
1317 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1318 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1319 test_process(test
, pa
, p
, g
->conf
, true, false);
1321 /* Test Case: Re-add BGP peer to peer-group. */
1322 test_log(test
, "case %02d: re-add peer [%s] to group [%s]", tc
++,
1324 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1325 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1326 p
->conf_if
? "interface " : "", g
->name
);
1327 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1328 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1329 test_process(test
, pa
, p
, g
->conf
, true, false);
1331 /* Test Case: Set flag on BGP peer-group. */
1332 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1334 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1335 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1336 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1337 test_process(test
, pa
, p
, g
->conf
, true, true);
1339 /* Test Case: Unset flag on BGP peer-group. */
1340 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1341 group_cmd
, g
->name
);
1342 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1343 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1344 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1345 test_process(test
, pa
, p
, g
->conf
, true, false);
1347 /* Test Case: Set flag on BGP peer-group. */
1348 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1350 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1351 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1352 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1353 test_process(test
, pa
, p
, g
->conf
, true, true);
1355 /* Test Case: Re-set flag on BGP peer. */
1356 test_log(test
, "case %02d: re-set %s [%s] on [%s]", tc
++, type
,
1358 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1359 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1360 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1361 test_process(test
, pa
, p
, g
->conf
, true, true);
1363 /* Test Case: Unset flag on BGP peer. */
1364 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1366 test_execute(test
, "%sneighbor %s %s", dcp
, p
->host
, peer_cmd
);
1367 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1368 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1369 test_process(test
, pa
, p
, g
->conf
, false, true);
1371 /* Test Case: Unset flag on BGP peer-group. */
1372 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1373 group_cmd
, g
->name
);
1374 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1375 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1376 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1377 test_process(test
, pa
, p
, g
->conf
, false, false);
1379 /* Test Case: Set flag on BGP peer. */
1380 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1382 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1383 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1384 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1385 test_process(test
, pa
, p
, g
->conf
, true, false);
1388 static const struct frr_yang_module_info
*const bgpd_yang_modules
[] = {
1391 &frr_interface_info
,
1392 &frr_route_map_info
,
1397 static void bgp_startup(void)
1400 zlog_aux_init("NONE: ", LOG_DEBUG
);
1401 zprivs_preinit(&bgpd_privs
);
1402 zprivs_init(&bgpd_privs
);
1404 master
= thread_master_create(NULL
);
1405 nb_init(master
, bgpd_yang_modules
, array_size(bgpd_yang_modules
), false);
1406 bgp_master_init(master
, BGP_SOCKET_SNDBUF_SIZE
, list_new());
1407 bgp_option_set(BGP_OPT_NO_LISTEN
);
1408 vrf_init(NULL
, NULL
, NULL
, NULL
, NULL
);
1414 static void bgp_shutdown(void)
1417 struct listnode
*node
, *nnode
;
1421 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
1425 bgp_route_map_terminate();
1427 bgp_pthreads_finish();
1428 access_list_add_hook(NULL
);
1429 access_list_delete_hook(NULL
);
1430 access_list_reset();
1431 as_list_add_hook(NULL
);
1432 as_list_delete_hook(NULL
);
1434 prefix_list_add_hook(NULL
);
1435 prefix_list_delete_hook(NULL
);
1436 prefix_list_reset();
1437 community_list_terminate(bgp_clist
);
1439 #ifdef ENABLE_BGP_VNC
1440 vnc_zebra_destroy();
1442 bgp_zebra_destroy();
1444 bf_free(bm
->rd_idspace
);
1445 list_delete(&bm
->bgp
);
1446 memset(bm
, 0, sizeof(*bm
));
1452 zprivs_terminate(&bgpd_privs
);
1453 thread_master_free(master
);
1460 struct list
*pa_list
;
1461 struct test_peer_attr
*pa
, *pac
;
1462 struct listnode
*node
, *nnode
;
1466 pa_list
= list_new();
1468 while (test_peer_attrs
[i
].cmd
) {
1469 pa
= &test_peer_attrs
[i
++];
1471 /* Just copy the peer attribute structure for global flags. */
1472 if (is_attr_type_global(pa
->type
)) {
1473 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1474 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1475 listnode_add(pa_list
, pac
);
1479 /* Fallback to default families if not specified. */
1480 if (!pa
->families
[0].afi
&& !pa
->families
[0].safi
)
1481 memcpy(&pa
->families
, test_default_families
,
1482 sizeof(test_default_families
));
1484 /* Add peer attribute definition for each address family. */
1486 while (pa
->families
[ii
].afi
&& pa
->families
[ii
].safi
) {
1487 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1488 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1490 pac
->afi
= pa
->families
[ii
].afi
;
1491 pac
->safi
= pa
->families
[ii
].safi
;
1492 listnode_add(pa_list
, pac
);
1498 for (ALL_LIST_ELEMENTS(pa_list
, node
, nnode
, pa
)) {
1502 /* Build test description string. */
1503 if (pa
->afi
&& pa
->safi
)
1504 desc
= str_printf("peer\\%s-%s\\%s",
1505 str_from_afi(pa
->afi
),
1506 str_from_safi(pa
->safi
), pa
->cmd
);
1508 desc
= str_printf("peer\\%s", pa
->cmd
);
1510 /* Initialize new test instance. */
1511 test
= test_new(desc
, pa
->o
.use_ibgp
, pa
->o
.use_iface_peer
);
1512 XFREE(MTYPE_TMP
, desc
);
1514 /* Execute tests and finish test instance. */
1515 test_peer_attr(test
, pa
);
1518 /* Print empty line as spacer. */
1521 /* Free memory used for peer-attr declaration. */
1522 XFREE(MTYPE_TMP
, pa
);
1525 list_delete(&pa_list
);