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
24 #include "bgpd/bgpd.h"
25 #include "bgpd/bgp_attr.h"
26 #include "bgpd/bgp_regex.h"
27 #include "bgpd/bgp_clist.h"
28 #include "bgpd/bgp_dump.h"
29 #include "bgpd/bgp_filter.h"
30 #include "bgpd/bgp_route.h"
31 #include "bgpd/bgp_vty.h"
32 #include "bgpd/bgp_zebra.h"
33 #include "bgpd/bgp_network.h"
36 #include "bgpd/rfapi/rfapi_backend.h"
39 #define OUT_SYMBOL_INFO "\u25ba"
40 #define OUT_SYMBOL_OK "\u2714"
41 #define OUT_SYMBOL_NOK "\u2716"
43 #define TEST_ASSERT(T, C) \
45 if ((T)->state != TEST_SUCCESS || (C)) \
47 (T)->state = TEST_ASSERT_ERROR; \
49 asprintfrr(MTYPE_TMP, "assertion failed: %s (%s:%d)", \
50 (#C), __FILE__, __LINE__); \
53 #define TEST_ASSERT_EQ(T, A, B) \
55 if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
57 (T)->state = TEST_ASSERT_ERROR; \
58 (T)->error = asprintfrr( \
60 "assertion failed: %s[%lld] == [%lld]%s (%s:%d)", \
61 (#A), (long long)(A), (long long)(B), (#B), __FILE__, \
65 #define TEST_HANDLER_MAX 5
66 #define TEST_HANDLER(name) _test_handler_##name
67 #define TEST_HANDLER_DECL(name) \
68 static void _test_handler_##name( \
69 struct test *test, struct test_peer_attr *pa, \
70 struct peer *peer, struct peer *group, bool peer_set, \
73 #define TEST_ATTR_HANDLER_DECL(name, attr, pval, gval) \
74 TEST_HANDLER_DECL(name) \
77 TEST_ASSERT_EQ(test, peer->attr, (pval)); \
78 else if (peer_group_active(peer) && group_set) \
79 TEST_ASSERT_EQ(test, peer->attr, (gval)); \
81 TEST_ASSERT_EQ(test, group->attr, (gval)); \
83 TEST_HANDLER_DECL(name)
85 #define TEST_STR_ATTR_HANDLER_DECL(name, attr, pval, gval) \
86 TEST_HANDLER_DECL(name) \
89 TEST_ASSERT(test, peer->attr != NULL); \
90 TEST_ASSERT(test, !strcmp(peer->attr, (pval))); \
91 } else if (peer_group_active(peer) && group_set) { \
92 TEST_ASSERT(test, peer->attr != NULL); \
93 TEST_ASSERT(test, !strcmp(peer->attr, (gval))); \
96 TEST_ASSERT(test, group->attr != NULL); \
97 TEST_ASSERT(test, !strcmp(group->attr, (gval))); \
100 TEST_HANDLER_DECL(name)
102 #define TEST_SU_ATTR_HANDLER_DECL(name, attr, pval, gval) \
103 TEST_HANDLER_DECL(name) \
105 union sockunion su; \
107 str2sockunion(pval, &su); \
108 TEST_ASSERT(test, !sockunion_cmp(peer->attr, &su)); \
109 } else if (peer_group_active(peer) && group_set) { \
110 str2sockunion(gval, &su); \
111 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
114 str2sockunion(gval, &su); \
115 TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
118 TEST_HANDLER_DECL(name)
120 /* Required variables to link in libbgp */
121 struct zebra_privs_t bgpd_privs
= {0};
122 struct thread_master
*master
;
134 enum test_peer_attr_type
{
136 PEER_AT_AF_FILTER
= 1,
137 PEER_AT_AF_CUSTOM
= 2,
138 PEER_AT_GLOBAL_FLAG
= 3,
139 PEER_AT_GLOBAL_CUSTOM
= 4
143 enum test_state state
;
151 struct peer_group
*group
;
162 const char *peer_address
;
163 const char *peer_interface
;
164 const char *peer_group
;
167 struct test_peer_family
{
172 struct test_peer_attr
{
174 const char *peer_cmd
;
175 const char *group_cmd
;
177 enum test_peer_attr_type type
;
190 bool skip_xfer_cases
;
195 struct test_peer_family families
[AFI_MAX
* SAFI_MAX
];
197 void (*handlers
[TEST_HANDLER_MAX
])(struct test
*test
,
198 struct test_peer_attr
*pa
,
200 struct peer
*group
, bool peer_set
,
204 static struct test_config cfg
= {
207 .peer_address
= "1.1.1.1",
208 .peer_interface
= "IP-TEST",
209 .peer_group
= "PG-TEST",
212 static struct test_peer_family test_default_families
[] = {
213 {.afi
= AFI_IP
, .safi
= SAFI_UNICAST
},
214 {.afi
= AFI_IP
, .safi
= SAFI_MULTICAST
},
215 {.afi
= AFI_IP6
, .safi
= SAFI_UNICAST
},
216 {.afi
= AFI_IP6
, .safi
= SAFI_MULTICAST
},
219 TEST_ATTR_HANDLER_DECL(advertisement_interval
, v_routeadv
, 10, 20);
220 TEST_STR_ATTR_HANDLER_DECL(password
, password
, "FRR-Peer", "FRR-Group");
221 TEST_ATTR_HANDLER_DECL(local_as
, change_local_as
, 1, 2);
222 TEST_ATTR_HANDLER_DECL(timers_1
, keepalive
, 10, 20);
223 TEST_ATTR_HANDLER_DECL(timers_2
, holdtime
, 30, 60);
224 TEST_ATTR_HANDLER_DECL(addpath_types
, addpath_type
[pa
->afi
][pa
->safi
],
225 BGP_ADDPATH_ALL
, BGP_ADDPATH_BEST_PER_AS
);
226 TEST_SU_ATTR_HANDLER_DECL(update_source_su
, update_source
, "255.255.255.1",
228 TEST_STR_ATTR_HANDLER_DECL(update_source_if
, update_if
, "IF-PEER", "IF-GROUP");
230 TEST_ATTR_HANDLER_DECL(allowas_in
, allowas_in
[pa
->afi
][pa
->safi
], 1, 2);
231 TEST_STR_ATTR_HANDLER_DECL(default_originate_route_map
,
232 default_rmap
[pa
->afi
][pa
->safi
].name
, "RM-PEER",
234 TEST_STR_ATTR_HANDLER_DECL(
236 filter
[pa
->afi
][pa
->safi
].dlist
[pa
->u
.filter
.direct
].name
, "DL-PEER",
238 TEST_STR_ATTR_HANDLER_DECL(
239 filter_list
, filter
[pa
->afi
][pa
->safi
].aslist
[pa
->u
.filter
.direct
].name
,
240 "FL-PEER", "FL-GROUP");
241 TEST_ATTR_HANDLER_DECL(maximum_prefix
, pmax
[pa
->afi
][pa
->safi
], 10, 20);
242 TEST_ATTR_HANDLER_DECL(maximum_prefix_threshold
,
243 pmax_threshold
[pa
->afi
][pa
->safi
], 1, 2);
244 TEST_ATTR_HANDLER_DECL(maximum_prefix_restart
, pmax_restart
[pa
->afi
][pa
->safi
],
246 TEST_STR_ATTR_HANDLER_DECL(
247 prefix_list
, filter
[pa
->afi
][pa
->safi
].plist
[pa
->u
.filter
.direct
].name
,
248 "PL-PEER", "PL-GROUP");
249 TEST_STR_ATTR_HANDLER_DECL(
250 route_map
, filter
[pa
->afi
][pa
->safi
].map
[pa
->u
.filter
.direct
].name
,
251 "RM-PEER", "RM-GROUP");
252 TEST_STR_ATTR_HANDLER_DECL(unsuppress_map
, filter
[pa
->afi
][pa
->safi
].usmap
.name
,
253 "UM-PEER", "UM-GROUP");
254 TEST_ATTR_HANDLER_DECL(weight
, weight
[pa
->afi
][pa
->safi
], 100, 200);
256 /* clang-format off */
257 static struct test_peer_attr test_peer_attrs
[] = {
258 /* Peer Attributes */
260 .cmd
= "advertisement-interval",
261 .peer_cmd
= "advertisement-interval 10",
262 .group_cmd
= "advertisement-interval 20",
263 .u
.flag
= PEER_FLAG_ROUTEADV
,
264 .type
= PEER_AT_GLOBAL_FLAG
,
265 .handlers
[0] = TEST_HANDLER(advertisement_interval
),
268 .cmd
= "capability dynamic",
269 .u
.flag
= PEER_FLAG_DYNAMIC_CAPABILITY
,
270 .type
= PEER_AT_GLOBAL_FLAG
,
273 .cmd
= "capability extended-nexthop",
274 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
275 .type
= PEER_AT_GLOBAL_FLAG
,
278 .cmd
= "capability extended-nexthop",
279 .u
.flag
= PEER_FLAG_CAPABILITY_ENHE
,
280 .type
= PEER_AT_GLOBAL_FLAG
,
281 .o
.invert_peer
= true,
282 .o
.use_iface_peer
= true,
285 .cmd
= "capability software-version",
286 .u
.flag
= PEER_FLAG_CAPABILITY_SOFT_VERSION
,
287 .type
= PEER_AT_GLOBAL_FLAG
,
290 .cmd
= "capability software-version",
291 .u
.flag
= PEER_FLAG_CAPABILITY_SOFT_VERSION
,
292 .type
= PEER_AT_GLOBAL_FLAG
,
293 .o
.invert_peer
= true,
294 .o
.use_iface_peer
= true,
297 .cmd
= "description",
298 .peer_cmd
= "description FRR Peer",
299 .group_cmd
= "description FRR Group",
300 .type
= PEER_AT_GLOBAL_CUSTOM
,
303 .cmd
= "disable-connected-check",
304 .u
.flag
= PEER_FLAG_DISABLE_CONNECTED_CHECK
,
305 .type
= PEER_AT_GLOBAL_FLAG
,
308 .cmd
= "dont-capability-negotiate",
309 .u
.flag
= PEER_FLAG_DONT_CAPABILITY
,
310 .type
= PEER_AT_GLOBAL_FLAG
,
313 .cmd
= "enforce-first-as",
314 .u
.flag
= PEER_FLAG_ENFORCE_FIRST_AS
,
315 .type
= PEER_AT_GLOBAL_FLAG
,
319 .peer_cmd
= "local-as 1",
320 .group_cmd
= "local-as 2",
321 .u
.flag
= PEER_FLAG_LOCAL_AS
,
322 .type
= PEER_AT_GLOBAL_FLAG
,
323 .handlers
[0] = TEST_HANDLER(local_as
),
326 .cmd
= "local-as 1 no-prepend",
327 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_NO_PREPEND
,
328 .type
= PEER_AT_GLOBAL_FLAG
,
331 .cmd
= "local-as 1 no-prepend replace-as",
332 .u
.flag
= PEER_FLAG_LOCAL_AS
| PEER_FLAG_LOCAL_AS_REPLACE_AS
,
333 .type
= PEER_AT_GLOBAL_FLAG
,
336 .cmd
= "override-capability",
337 .u
.flag
= PEER_FLAG_OVERRIDE_CAPABILITY
,
338 .type
= PEER_AT_GLOBAL_FLAG
,
342 .u
.flag
= PEER_FLAG_PASSIVE
,
343 .type
= PEER_AT_GLOBAL_FLAG
,
347 .peer_cmd
= "password FRR-Peer",
348 .group_cmd
= "password FRR-Group",
349 .u
.flag
= PEER_FLAG_PASSWORD
,
350 .type
= PEER_AT_GLOBAL_FLAG
,
351 .handlers
[0] = TEST_HANDLER(password
),
355 .u
.flag
= PEER_FLAG_SHUTDOWN
,
356 .type
= PEER_AT_GLOBAL_FLAG
,
359 .cmd
= "strict-capability-match",
360 .u
.flag
= PEER_FLAG_STRICT_CAP_MATCH
,
361 .type
= PEER_AT_GLOBAL_FLAG
,
365 .peer_cmd
= "timers 10 30",
366 .group_cmd
= "timers 20 60",
367 .u
.flag
= PEER_FLAG_TIMER
,
368 .type
= PEER_AT_GLOBAL_FLAG
,
369 .handlers
[0] = TEST_HANDLER(timers_1
),
370 .handlers
[1] = TEST_HANDLER(timers_2
),
373 .cmd
= "timers connect",
374 .peer_cmd
= "timers connect 10",
375 .group_cmd
= "timers connect 20",
376 .u
.flag
= PEER_FLAG_TIMER_CONNECT
,
377 .type
= PEER_AT_GLOBAL_FLAG
,
380 .cmd
= "update-source",
381 .peer_cmd
= "update-source 255.255.255.1",
382 .group_cmd
= "update-source 255.255.255.2",
383 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
384 .type
= PEER_AT_GLOBAL_FLAG
,
385 .handlers
[0] = TEST_HANDLER(update_source_su
),
388 .cmd
= "update-source",
389 .peer_cmd
= "update-source IF-PEER",
390 .group_cmd
= "update-source IF-GROUP",
391 .u
.flag
= PEER_FLAG_UPDATE_SOURCE
,
392 .type
= PEER_AT_GLOBAL_FLAG
,
393 .handlers
[0] = TEST_HANDLER(update_source_if
),
396 /* Address Family Attributes */
399 .peer_cmd
= "addpath-tx-all-paths",
400 .group_cmd
= "addpath-tx-bestpath-per-AS",
401 .type
= PEER_AT_AF_CUSTOM
,
402 .handlers
[0] = TEST_HANDLER(addpath_types
),
406 .peer_cmd
= "allowas-in 1",
407 .group_cmd
= "allowas-in 2",
408 .u
.flag
= PEER_FLAG_ALLOWAS_IN
,
409 .handlers
[0] = TEST_HANDLER(allowas_in
),
412 .cmd
= "allowas-in origin",
413 .u
.flag
= PEER_FLAG_ALLOWAS_IN_ORIGIN
,
416 .cmd
= "as-override",
417 .u
.flag
= PEER_FLAG_AS_OVERRIDE
,
420 .cmd
= "attribute-unchanged as-path",
421 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
,
424 .cmd
= "attribute-unchanged next-hop",
425 .u
.flag
= PEER_FLAG_NEXTHOP_UNCHANGED
,
428 .cmd
= "attribute-unchanged med",
429 .u
.flag
= PEER_FLAG_MED_UNCHANGED
,
432 .cmd
= "attribute-unchanged as-path next-hop",
433 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
434 | PEER_FLAG_NEXTHOP_UNCHANGED
,
437 .cmd
= "attribute-unchanged as-path med",
438 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
439 | PEER_FLAG_MED_UNCHANGED
,
442 .cmd
= "attribute-unchanged as-path next-hop med",
443 .u
.flag
= PEER_FLAG_AS_PATH_UNCHANGED
444 | PEER_FLAG_NEXTHOP_UNCHANGED
445 | PEER_FLAG_MED_UNCHANGED
,
448 .cmd
= "capability orf prefix-list send",
449 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
,
452 .cmd
= "capability orf prefix-list receive",
453 .u
.flag
= PEER_FLAG_ORF_PREFIX_RM
,
456 .cmd
= "capability orf prefix-list both",
457 .u
.flag
= PEER_FLAG_ORF_PREFIX_SM
| PEER_FLAG_ORF_PREFIX_RM
,
460 .cmd
= "default-originate",
461 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
464 .cmd
= "default-originate route-map",
465 .peer_cmd
= "default-originate route-map RM-PEER",
466 .group_cmd
= "default-originate route-map RM-GROUP",
467 .u
.flag
= PEER_FLAG_DEFAULT_ORIGINATE
,
468 .handlers
[0] = TEST_HANDLER(default_originate_route_map
),
471 .cmd
= "distribute-list",
472 .peer_cmd
= "distribute-list DL-PEER in",
473 .group_cmd
= "distribute-list DL-GROUP in",
474 .type
= PEER_AT_AF_FILTER
,
475 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
476 .u
.filter
.direct
= FILTER_IN
,
477 .handlers
[0] = TEST_HANDLER(distribute_list
),
480 .cmd
= "distribute-list",
481 .peer_cmd
= "distribute-list DL-PEER out",
482 .group_cmd
= "distribute-list DL-GROUP out",
483 .type
= PEER_AT_AF_FILTER
,
484 .u
.filter
.flag
= PEER_FT_DISTRIBUTE_LIST
,
485 .u
.filter
.direct
= FILTER_OUT
,
486 .handlers
[0] = TEST_HANDLER(distribute_list
),
489 .cmd
= "filter-list",
490 .peer_cmd
= "filter-list FL-PEER in",
491 .group_cmd
= "filter-list FL-GROUP in",
492 .type
= PEER_AT_AF_FILTER
,
493 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
494 .u
.filter
.direct
= FILTER_IN
,
495 .handlers
[0] = TEST_HANDLER(filter_list
),
498 .cmd
= "filter-list",
499 .peer_cmd
= "filter-list FL-PEER out",
500 .group_cmd
= "filter-list FL-GROUP out",
501 .type
= PEER_AT_AF_FILTER
,
502 .u
.filter
.flag
= PEER_FT_FILTER_LIST
,
503 .u
.filter
.direct
= FILTER_OUT
,
504 .handlers
[0] = TEST_HANDLER(filter_list
),
507 .cmd
= "maximum-prefix",
508 .peer_cmd
= "maximum-prefix 10",
509 .group_cmd
= "maximum-prefix 20",
510 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
511 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
514 .cmd
= "maximum-prefix",
515 .peer_cmd
= "maximum-prefix 10 restart 100",
516 .group_cmd
= "maximum-prefix 20 restart 200",
517 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
518 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
519 .handlers
[1] = TEST_HANDLER(maximum_prefix_restart
),
522 .cmd
= "maximum-prefix",
523 .peer_cmd
= "maximum-prefix 10 1 restart 100",
524 .group_cmd
= "maximum-prefix 20 2 restart 200",
525 .u
.flag
= PEER_FLAG_MAX_PREFIX
,
526 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
527 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
528 .handlers
[2] = TEST_HANDLER(maximum_prefix_restart
),
531 .cmd
= "maximum-prefix",
532 .peer_cmd
= "maximum-prefix 10 warning-only",
533 .group_cmd
= "maximum-prefix 20 warning-only",
534 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
535 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
538 .cmd
= "maximum-prefix",
539 .peer_cmd
= "maximum-prefix 10 1 warning-only",
540 .group_cmd
= "maximum-prefix 20 2 warning-only",
541 .u
.flag
= PEER_FLAG_MAX_PREFIX
| PEER_FLAG_MAX_PREFIX_WARNING
,
542 .handlers
[0] = TEST_HANDLER(maximum_prefix
),
543 .handlers
[1] = TEST_HANDLER(maximum_prefix_threshold
),
546 .cmd
= "next-hop-self",
547 .u
.flag
= PEER_FLAG_NEXTHOP_SELF
,
550 .cmd
= "next-hop-self force",
551 .u
.flag
= PEER_FLAG_FORCE_NEXTHOP_SELF
,
554 .cmd
= "prefix-list",
555 .peer_cmd
= "prefix-list PL-PEER in",
556 .group_cmd
= "prefix-list PL-GROUP in",
557 .type
= PEER_AT_AF_FILTER
,
558 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
559 .u
.filter
.direct
= FILTER_IN
,
560 .handlers
[0] = TEST_HANDLER(prefix_list
),
563 .cmd
= "prefix-list",
564 .peer_cmd
= "prefix-list PL-PEER out",
565 .group_cmd
= "prefix-list PL-GROUP out",
566 .type
= PEER_AT_AF_FILTER
,
567 .u
.filter
.flag
= PEER_FT_PREFIX_LIST
,
568 .u
.filter
.direct
= FILTER_OUT
,
569 .handlers
[0] = TEST_HANDLER(prefix_list
),
572 .cmd
= "remove-private-AS",
573 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
,
576 .cmd
= "remove-private-AS all",
577 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
578 | PEER_FLAG_REMOVE_PRIVATE_AS_ALL
,
581 .cmd
= "remove-private-AS replace-AS",
582 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS
583 | PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE
,
586 .cmd
= "remove-private-AS all replace-AS",
587 .u
.flag
= PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE
,
591 .peer_cmd
= "route-map RM-PEER in",
592 .group_cmd
= "route-map RM-GROUP in",
593 .type
= PEER_AT_AF_FILTER
,
594 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
595 .u
.filter
.direct
= FILTER_IN
,
596 .handlers
[0] = TEST_HANDLER(route_map
),
600 .peer_cmd
= "route-map RM-PEER out",
601 .group_cmd
= "route-map RM-GROUP out",
602 .type
= PEER_AT_AF_FILTER
,
603 .u
.filter
.flag
= PEER_FT_ROUTE_MAP
,
604 .u
.filter
.direct
= FILTER_OUT
,
605 .handlers
[0] = TEST_HANDLER(route_map
),
608 .cmd
= "route-reflector-client",
609 .u
.flag
= PEER_FLAG_REFLECTOR_CLIENT
,
611 .o
.skip_xfer_cases
= true,
614 .cmd
= "route-server-client",
615 .u
.flag
= PEER_FLAG_RSERVER_CLIENT
,
618 .cmd
= "send-community",
619 .u
.flag
= PEER_FLAG_SEND_COMMUNITY
,
620 .o
.invert_peer
= true,
621 .o
.invert_group
= true,
624 .cmd
= "send-community extended",
625 .u
.flag
= PEER_FLAG_SEND_EXT_COMMUNITY
,
626 .o
.invert_peer
= true,
627 .o
.invert_group
= true,
630 .cmd
= "send-community large",
631 .u
.flag
= PEER_FLAG_SEND_LARGE_COMMUNITY
,
632 .o
.invert_peer
= true,
633 .o
.invert_group
= true,
636 .cmd
= "soft-reconfiguration inbound",
637 .u
.flag
= PEER_FLAG_SOFT_RECONFIG
,
640 .cmd
= "unsuppress-map",
641 .peer_cmd
= "unsuppress-map UM-PEER",
642 .group_cmd
= "unsuppress-map UM-GROUP",
643 .type
= PEER_AT_AF_FILTER
,
644 .u
.filter
.flag
= PEER_FT_UNSUPPRESS_MAP
,
645 .u
.filter
.direct
= 0,
646 .handlers
[0] = TEST_HANDLER(unsuppress_map
),
650 .peer_cmd
= "weight 100",
651 .group_cmd
= "weight 200",
652 .u
.flag
= PEER_FLAG_WEIGHT
,
653 .handlers
[0] = TEST_HANDLER(weight
),
657 /* clang-format on */
659 static const char *str_from_afi(afi_t afi
)
667 return "<unknown AFI>";
671 static const char *str_from_safi(safi_t safi
)
679 return "<unknown SAFI>";
683 static const char *str_from_attr_type(enum test_peer_attr_type at
)
686 case PEER_AT_GLOBAL_FLAG
:
688 case PEER_AT_AF_FLAG
:
690 case PEER_AT_AF_FILTER
:
692 case PEER_AT_GLOBAL_CUSTOM
:
693 case PEER_AT_AF_CUSTOM
:
700 static bool is_attr_type_global(enum test_peer_attr_type at
)
702 return at
== PEER_AT_GLOBAL_FLAG
|| at
== PEER_AT_GLOBAL_CUSTOM
;
706 static void test_log(struct test
*test
, const char *fmt
, ...)
710 /* Skip logging if test instance has previously failed. */
711 if (test
->state
!= TEST_SUCCESS
)
714 /* Store formatted log message. */
716 listnode_add(test
->log
, vasprintfrr(MTYPE_TMP
, fmt
, ap
));
721 static void test_execute(struct test
*test
, const char *fmt
, ...)
728 /* Skip execution if test instance has previously failed. */
729 if (test
->state
!= TEST_SUCCESS
)
732 /* Format command string with variadic arguments. */
734 cmd
= vasprintfrr(MTYPE_TMP
, fmt
, ap
);
737 test
->state
= TEST_INTERNAL_ERROR
;
738 test
->error
= asprintfrr(
739 MTYPE_TMP
, "could not format command string [%s]", fmt
);
743 /* Tokenize formatted command string. */
744 vline
= cmd_make_strvec(cmd
);
746 test
->state
= TEST_INTERNAL_ERROR
;
747 test
->error
= asprintfrr(
749 "tokenizing command string [%s] returned empty result",
751 XFREE(MTYPE_TMP
, cmd
);
756 /* Execute command (non-strict). */
757 ret
= cmd_execute_command(vline
, test
->vty
, NULL
, 0);
758 if (ret
!= CMD_SUCCESS
) {
759 test
->state
= TEST_COMMAND_ERROR
;
760 test
->error
= asprintfrr(
762 "execution of command [%s] has failed with code [%d]",
767 cmd_free_strvec(vline
);
768 XFREE(MTYPE_TMP
, cmd
);
772 static void test_config(struct test
*test
, const char *fmt
, bool invert
,
780 /* Skip execution if test instance has previously failed. */
781 if (test
->state
!= TEST_SUCCESS
)
784 /* Format matcher string with variadic arguments. */
786 matcher
= vasprintfrr(MTYPE_TMP
, fmt
, apc
);
789 test
->state
= TEST_INTERNAL_ERROR
;
790 test
->error
= asprintfrr(
791 MTYPE_TMP
, "could not format matcher string [%s]", fmt
);
795 /* Fetch BGP configuration into buffer. */
796 bgp_config_write(test
->vty
);
797 config
= buffer_getstr(test
->vty
->obuf
);
798 buffer_reset(test
->vty
->obuf
);
800 /* Match config against matcher. */
801 matched
= !!strstr(config
, matcher
);
802 if (!matched
&& !invert
) {
803 test
->state
= TEST_CONFIG_ERROR
;
804 test
->error
= asprintfrr(MTYPE_TMP
,
805 "expected config [%s] to be present",
807 } else if (matched
&& invert
) {
808 test
->state
= TEST_CONFIG_ERROR
;
809 test
->error
= asprintfrr(MTYPE_TMP
,
810 "expected config [%s] to be absent",
814 /* Free memory and return. */
815 XFREE(MTYPE_TMP
, matcher
);
816 XFREE(MTYPE_TMP
, config
);
820 static void test_config_present(struct test
*test
, const char *fmt
, ...)
825 test_config(test
, fmt
, false, ap
);
830 static void test_config_absent(struct test
*test
, const char *fmt
, ...)
835 test_config(test
, fmt
, true, ap
);
839 static void test_initialize(struct test
*test
)
843 /* Skip execution if test instance has previously failed. */
844 if (test
->state
!= TEST_SUCCESS
)
847 /* Log message about (re)-initialization */
848 test_log(test
, "prepare: %sinitialize bgp test environment",
849 test
->bgp
? "re-" : "");
851 /* Attempt gracefully to purge previous BGP configuration. */
852 test_execute(test
, "no router bgp");
853 test
->state
= TEST_SUCCESS
;
855 /* Initialize BGP test environment. */
856 test_execute(test
, "router bgp %d", cfg
.local_asn
);
857 test_execute(test
, "no bgp default ipv4-unicast");
858 test_execute(test
, "neighbor %s peer-group", cfg
.peer_group
);
859 if (test
->o
.use_iface_peer
) {
860 test_execute(test
, "neighbor %s interface", cfg
.peer_interface
);
861 test_execute(test
, "neighbor %s remote-as %d",
863 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
865 test_execute(test
, "neighbor %s remote-as %d", cfg
.peer_address
,
866 test
->o
.use_ibgp
? cfg
.local_asn
: cfg
.peer_asn
);
869 if (test
->state
!= TEST_SUCCESS
)
872 /* Fetch default BGP instance. */
873 test
->bgp
= bgp_get_default();
875 test
->state
= TEST_INTERNAL_ERROR
;
876 test
->error
= asprintfrr(
877 MTYPE_TMP
, "could not retrieve default bgp instance");
881 /* Fetch peer instance. */
882 if (test
->o
.use_iface_peer
) {
884 peer_lookup_by_conf_if(test
->bgp
, cfg
.peer_interface
);
886 str2sockunion(cfg
.peer_address
, &su
);
887 test
->peer
= peer_lookup(test
->bgp
, &su
);
890 test
->state
= TEST_INTERNAL_ERROR
;
891 test
->error
= asprintfrr(
893 "could not retrieve instance of bgp peer [%s]",
898 /* Fetch peer-group instance. */
899 test
->group
= peer_group_lookup(test
->bgp
, cfg
.peer_group
);
901 test
->state
= TEST_INTERNAL_ERROR
;
902 test
->error
= asprintfrr(
904 "could not retrieve instance of bgp peer-group [%s]",
910 static struct test
*test_new(const char *desc
, bool use_ibgp
,
915 test
= XCALLOC(MTYPE_TMP
, sizeof(struct test
));
916 test
->state
= TEST_SUCCESS
;
917 test
->desc
= XSTRDUP(MTYPE_TMP
, desc
);
918 test
->log
= list_new();
919 test
->o
.use_ibgp
= use_ibgp
;
920 test
->o
.use_iface_peer
= use_iface_peer
;
922 test
->vty
= vty_new();
923 test
->vty
->type
= VTY_TERM
;
924 test
->vty
->node
= CONFIG_NODE
;
926 test_initialize(test
);
931 static void test_finish(struct test
*test
)
934 struct listnode
*node
, *nnode
;
936 /* Print test output header. */
937 printf("%s [test] %s\n",
938 (test
->state
== TEST_SUCCESS
) ? OUT_SYMBOL_OK
: OUT_SYMBOL_NOK
,
941 /* Print test log messages. */
942 for (ALL_LIST_ELEMENTS(test
->log
, node
, nnode
, msg
)) {
943 printf("%s %s\n", OUT_SYMBOL_INFO
, msg
);
944 XFREE(MTYPE_TMP
, msg
);
947 /* Print test error message if available. */
948 if (test
->state
!= TEST_SUCCESS
&& test
->error
)
949 printf("%s error: %s\n", OUT_SYMBOL_INFO
, test
->error
);
951 /* Print machine-readable result of test. */
952 printf("%s\n", test
->state
== TEST_SUCCESS
? "OK" : "failed");
954 /* Cleanup allocated memory. */
956 vty_close(test
->vty
);
960 list_delete(&test
->log
);
962 XFREE(MTYPE_TMP
, test
->desc
);
964 XFREE(MTYPE_TMP
, test
->error
);
965 XFREE(MTYPE_TMP
, test
);
968 static void test_peer_flags(struct test
*test
, struct test_peer_attr
*pa
,
969 struct peer
*peer
, bool exp_val
, bool exp_ovrd
)
971 bool exp_inv
, cur_val
, cur_ovrd
, cur_inv
;
973 /* Skip execution if test instance has previously failed. */
974 if (test
->state
!= TEST_SUCCESS
)
977 /* Detect if flag is meant to be inverted. */
978 if (CHECK_FLAG(peer
->sflags
, PEER_STATUS_GROUP
))
979 exp_inv
= pa
->o
.invert_group
;
981 exp_inv
= pa
->o
.invert_peer
;
983 /* Flip expected value if flag is inverted. */
986 /* Fetch current state of value, override and invert flags. */
987 if (pa
->type
== PEER_AT_GLOBAL_FLAG
) {
988 cur_val
= !!CHECK_FLAG(peer
->flags
, pa
->u
.flag
);
989 cur_ovrd
= !!CHECK_FLAG(peer
->flags_override
, pa
->u
.flag
);
990 cur_inv
= !!CHECK_FLAG(peer
->flags_invert
, pa
->u
.flag
);
991 } else /* if (pa->type == PEER_AT_AF_FLAG) */ {
992 cur_val
= !!CHECK_FLAG(peer
->af_flags
[pa
->afi
][pa
->safi
],
994 cur_ovrd
= !!CHECK_FLAG(
995 peer
->af_flags_override
[pa
->afi
][pa
->safi
], pa
->u
.flag
);
996 cur_inv
= !!CHECK_FLAG(peer
->af_flags_invert
[pa
->afi
][pa
->safi
],
1000 /* Assert expected flag states. */
1001 TEST_ASSERT_EQ(test
, cur_val
, exp_val
);
1002 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1003 TEST_ASSERT_EQ(test
, cur_inv
, exp_inv
);
1006 static void test_af_filter(struct test
*test
, struct test_peer_attr
*pa
,
1007 struct peer
*peer
, bool exp_state
, bool exp_ovrd
)
1010 struct bgp_filter
*filter
;
1012 /* Skip execution if test instance has previously failed. */
1013 if (test
->state
!= TEST_SUCCESS
)
1016 /* Fetch and assert current state of override flag. */
1017 cur_ovrd
= !!CHECK_FLAG(
1018 peer
->filter_override
[pa
->afi
][pa
->safi
][pa
->u
.filter
.direct
],
1021 TEST_ASSERT_EQ(test
, cur_ovrd
, exp_ovrd
);
1023 /* Assert that map/list matches expected state (set/unset). */
1024 filter
= &peer
->filter
[pa
->afi
][pa
->safi
];
1026 switch (pa
->u
.filter
.flag
) {
1027 case PEER_FT_DISTRIBUTE_LIST
:
1028 TEST_ASSERT_EQ(test
,
1029 !!(filter
->dlist
[pa
->u
.filter
.direct
].name
),
1032 case PEER_FT_FILTER_LIST
:
1033 TEST_ASSERT_EQ(test
,
1034 !!(filter
->aslist
[pa
->u
.filter
.direct
].name
),
1037 case PEER_FT_PREFIX_LIST
:
1038 TEST_ASSERT_EQ(test
,
1039 !!(filter
->plist
[pa
->u
.filter
.direct
].name
),
1042 case PEER_FT_ROUTE_MAP
:
1043 TEST_ASSERT_EQ(test
, !!(filter
->map
[pa
->u
.filter
.direct
].name
),
1046 case PEER_FT_UNSUPPRESS_MAP
:
1047 TEST_ASSERT_EQ(test
, !!(filter
->usmap
.name
), exp_state
);
1052 static void test_custom(struct test
*test
, struct test_peer_attr
*pa
,
1053 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1057 char *handler_error
;
1059 for (i
= 0; i
< TEST_HANDLER_MAX
; i
++) {
1060 /* Skip execution if test instance has previously failed. */
1061 if (test
->state
!= TEST_SUCCESS
)
1064 /* Skip further execution if handler is undefined. */
1065 if (!pa
->handlers
[i
])
1068 /* Execute custom handler. */
1069 pa
->handlers
[i
](test
, pa
, peer
, group
, peer_set
, group_set
);
1070 if (test
->state
!= TEST_SUCCESS
) {
1071 test
->state
= TEST_CUSTOM_ERROR
;
1072 handler_error
= test
->error
;
1073 test
->error
= asprintfrr(MTYPE_TMP
,
1074 "custom handler failed: %s",
1076 XFREE(MTYPE_TMP
, handler_error
);
1082 static void test_process(struct test
*test
, struct test_peer_attr
*pa
,
1083 struct peer
*peer
, struct peer
*group
, bool peer_set
,
1087 case PEER_AT_GLOBAL_FLAG
:
1088 case PEER_AT_AF_FLAG
:
1091 peer_set
|| (peer_group_active(peer
) && group_set
),
1093 test_peer_flags(test
, pa
, group
, group_set
, false);
1096 case PEER_AT_AF_FILTER
:
1099 peer_set
|| (peer_group_active(peer
) && group_set
),
1101 test_af_filter(test
, pa
, group
, group_set
, false);
1104 case PEER_AT_GLOBAL_CUSTOM
:
1105 case PEER_AT_AF_CUSTOM
:
1107 * Do nothing here - a custom handler can be executed, but this
1108 * is not required. This will allow defining peer attributes
1109 * which shall not be checked for flag/filter/other internal
1115 test
->state
= TEST_INTERNAL_ERROR
;
1116 test
->error
= asprintfrr(
1117 MTYPE_TMP
, "invalid attribute type: %d", pa
->type
);
1121 /* Attempt to call a custom handler if set for further processing. */
1122 test_custom(test
, pa
, peer
, group
, peer_set
, group_set
);
1125 static void test_peer_attr(struct test
*test
, struct test_peer_attr
*pa
)
1129 const char *ecp
= pa
->o
.invert_peer
? "no " : "";
1130 const char *dcp
= pa
->o
.invert_peer
? "" : "no ";
1131 const char *ecg
= pa
->o
.invert_group
? "no " : "";
1132 const char *dcg
= pa
->o
.invert_group
? "" : "no ";
1133 const char *peer_cmd
= pa
->peer_cmd
?: pa
->cmd
;
1134 const char *group_cmd
= pa
->group_cmd
?: pa
->cmd
;
1135 struct peer
*p
= test
->peer
;
1136 struct peer_group
*g
= test
->group
;
1138 /* Determine type and if test is address-family relevant */
1139 type
= str_from_attr_type(pa
->type
);
1141 test
->state
= TEST_INTERNAL_ERROR
;
1142 test
->error
= asprintfrr(
1143 MTYPE_TMP
, "invalid attribute type: %d", pa
->type
);
1148 * =====================================================================
1149 * Test Case Suite 1: Config persistence after adding peer to group
1151 * Example: If a peer attribute has value [1] and a group attribute has
1152 * value [2], the peer attribute value should be persisted when the peer
1153 * gets added to the peer-group.
1155 * This test suite is meant to test the group2peer functions which can
1156 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1158 * =====================================================================
1161 /* Test Preparation: Switch and activate address-family. */
1162 if (!is_attr_type_global(pa
->type
)) {
1163 test_log(test
, "prepare: switch address-family to [%s]",
1164 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1165 test_execute(test
, "address-family %s %s",
1166 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1167 test_execute(test
, "neighbor %s activate", g
->name
);
1168 test_execute(test
, "neighbor %s activate", p
->host
);
1171 /* Skip peer-group to peer transfer test cases if requested. */
1172 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SUCCESS
)
1173 test
->state
= TEST_SKIPPING
;
1175 /* Test Case: Set flag on BGP peer. */
1176 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1178 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1179 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1180 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1181 test_process(test
, pa
, p
, g
->conf
, true, false);
1183 /* Test Case: Set flag on BGP peer-group. */
1184 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1186 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1187 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1188 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1189 test_process(test
, pa
, p
, g
->conf
, true, true);
1191 /* Test Case: Add BGP peer to peer-group. */
1192 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1194 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1195 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1196 p
->conf_if
? "interface " : "", g
->name
);
1197 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1198 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1199 test_process(test
, pa
, p
, g
->conf
, true, true);
1201 /* Test Case: Unset flag on BGP peer-group. */
1202 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1203 group_cmd
, g
->name
);
1204 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1205 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1206 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1207 test_process(test
, pa
, p
, g
->conf
, true, false);
1210 * =====================================================================
1211 * Test Case Suite 2: Config inheritance after adding peer to group
1213 * Example: If a peer attribute has not been set and a group attribute
1214 * has a value of [2], the group attribute should be inherited to the
1215 * peer without flagging the newly set value as overridden.
1217 * This test suite is meant to test the group2peer functions which can
1218 * be found inside bgpd/bgpd.c, which are related to initial peer-group
1220 * =====================================================================
1223 /* Test Preparation: Re-initialize test environment. */
1224 test_initialize(test
);
1228 /* Test Preparation: Switch and activate address-family. */
1229 if (!is_attr_type_global(pa
->type
)) {
1230 test_log(test
, "prepare: switch address-family to [%s]",
1231 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1232 test_execute(test
, "address-family %s %s",
1233 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1234 test_execute(test
, "neighbor %s activate", g
->name
);
1235 test_execute(test
, "neighbor %s activate", p
->host
);
1238 /* Test Case: Set flag on BGP peer-group. */
1239 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1241 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1242 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1243 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1244 test_process(test
, pa
, p
, g
->conf
, false, true);
1246 /* Test Case: Add BGP peer to peer-group. */
1247 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1249 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1250 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1251 p
->conf_if
? "interface " : "", g
->name
);
1252 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1253 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1254 test_process(test
, pa
, p
, g
->conf
, false, true);
1256 /* Stop skipping test cases if previously enabled. */
1257 if (pa
->o
.skip_xfer_cases
&& test
->state
== TEST_SKIPPING
)
1258 test
->state
= TEST_SUCCESS
;
1261 * =====================================================================
1262 * Test Case Suite 3: Miscellaneous flag checks
1264 * This test suite does not focus on initial peer-group inheritance and
1265 * instead executes various different commands to set/unset attributes
1266 * on both peer- and group-level. These checks should always be executed
1268 * =====================================================================
1271 /* Test Preparation: Re-initialize test environment. */
1272 test_initialize(test
);
1276 /* Test Preparation: Switch and activate address-family. */
1277 if (!is_attr_type_global(pa
->type
)) {
1278 test_log(test
, "prepare: switch address-family to [%s]",
1279 get_afi_safi_str(pa
->afi
, pa
->safi
, false));
1280 test_execute(test
, "address-family %s %s",
1281 str_from_afi(pa
->afi
), str_from_safi(pa
->safi
));
1282 test_execute(test
, "neighbor %s activate", g
->name
);
1283 test_execute(test
, "neighbor %s activate", p
->host
);
1286 /* Test Case: Set flag on BGP peer. */
1287 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1289 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1290 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1291 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1292 test_process(test
, pa
, p
, g
->conf
, true, false);
1294 /* Test Case: Add BGP peer to peer-group. */
1295 test_log(test
, "case %02d: add peer [%s] to group [%s]", tc
++, p
->host
,
1297 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1298 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1299 p
->conf_if
? "interface " : "", g
->name
);
1300 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1301 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1302 test_process(test
, pa
, p
, g
->conf
, true, false);
1304 /* Test Case: Re-add BGP peer to peer-group. */
1305 test_log(test
, "case %02d: re-add peer [%s] to group [%s]", tc
++,
1307 test_execute(test
, "neighbor %s peer-group %s", p
->host
, g
->name
);
1308 test_config_present(test
, "neighbor %s %speer-group %s", p
->host
,
1309 p
->conf_if
? "interface " : "", g
->name
);
1310 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1311 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1312 test_process(test
, pa
, p
, g
->conf
, true, false);
1314 /* Test Case: Set flag on BGP peer-group. */
1315 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1317 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1318 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1319 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1320 test_process(test
, pa
, p
, g
->conf
, true, true);
1322 /* Test Case: Unset flag on BGP peer-group. */
1323 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1324 group_cmd
, g
->name
);
1325 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1326 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1327 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1328 test_process(test
, pa
, p
, g
->conf
, true, false);
1330 /* Test Case: Set flag on BGP peer-group. */
1331 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, group_cmd
,
1333 test_execute(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1334 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1335 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1336 test_process(test
, pa
, p
, g
->conf
, true, true);
1338 /* Test Case: Re-set flag on BGP peer. */
1339 test_log(test
, "case %02d: re-set %s [%s] on [%s]", tc
++, type
,
1341 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_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: Unset flag on BGP peer. */
1347 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1349 test_execute(test
, "%sneighbor %s %s", dcp
, p
->host
, peer_cmd
);
1350 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1351 test_config_present(test
, "%sneighbor %s %s", ecg
, g
->name
, group_cmd
);
1352 test_process(test
, pa
, p
, g
->conf
, false, true);
1354 /* Test Case: Unset flag on BGP peer-group. */
1355 test_log(test
, "case %02d: unset %s [%s] on [%s]", tc
++, type
,
1356 group_cmd
, g
->name
);
1357 test_execute(test
, "%sneighbor %s %s", dcg
, g
->name
, group_cmd
);
1358 test_config_absent(test
, "neighbor %s %s", p
->host
, pa
->cmd
);
1359 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1360 test_process(test
, pa
, p
, g
->conf
, false, false);
1362 /* Test Case: Set flag on BGP peer. */
1363 test_log(test
, "case %02d: set %s [%s] on [%s]", tc
++, type
, peer_cmd
,
1365 test_execute(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1366 test_config_present(test
, "%sneighbor %s %s", ecp
, p
->host
, peer_cmd
);
1367 test_config_absent(test
, "neighbor %s %s", g
->name
, pa
->cmd
);
1368 test_process(test
, pa
, p
, g
->conf
, true, false);
1371 static void bgp_startup(void)
1374 zlog_aux_init("NONE: ", LOG_DEBUG
);
1375 zprivs_preinit(&bgpd_privs
);
1376 zprivs_init(&bgpd_privs
);
1378 master
= thread_master_create(NULL
);
1379 nb_init(master
, NULL
, 0, false);
1380 bgp_master_init(master
, BGP_SOCKET_SNDBUF_SIZE
, list_new());
1381 bgp_option_set(BGP_OPT_NO_LISTEN
);
1382 vrf_init(NULL
, NULL
, NULL
, NULL
);
1388 static void bgp_shutdown(void)
1391 struct listnode
*node
, *nnode
;
1395 for (ALL_LIST_ELEMENTS(bm
->bgp
, node
, nnode
, bgp
))
1399 bgp_route_map_terminate();
1401 bgp_pthreads_finish();
1402 access_list_add_hook(NULL
);
1403 access_list_delete_hook(NULL
);
1404 access_list_reset();
1405 as_list_add_hook(NULL
);
1406 as_list_delete_hook(NULL
);
1408 prefix_list_add_hook(NULL
);
1409 prefix_list_delete_hook(NULL
);
1410 prefix_list_reset();
1411 community_list_terminate(bgp_clist
);
1413 #ifdef ENABLE_BGP_VNC
1414 vnc_zebra_destroy();
1416 bgp_zebra_destroy();
1418 bf_free(bm
->rd_idspace
);
1419 list_delete(&bm
->bgp
);
1420 memset(bm
, 0, sizeof(*bm
));
1426 zprivs_terminate(&bgpd_privs
);
1427 thread_master_free(master
);
1434 struct list
*pa_list
;
1435 struct test_peer_attr
*pa
, *pac
;
1436 struct listnode
*node
, *nnode
;
1440 pa_list
= list_new();
1442 while (test_peer_attrs
[i
].cmd
) {
1443 pa
= &test_peer_attrs
[i
++];
1445 /* Just copy the peer attribute structure for global flags. */
1446 if (is_attr_type_global(pa
->type
)) {
1447 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1448 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1449 listnode_add(pa_list
, pac
);
1453 /* Fallback to default families if not specified. */
1454 if (!pa
->families
[0].afi
&& !pa
->families
[0].safi
)
1455 memcpy(&pa
->families
, test_default_families
,
1456 sizeof(test_default_families
));
1458 /* Add peer attribute definition for each address family. */
1460 while (pa
->families
[ii
].afi
&& pa
->families
[ii
].safi
) {
1461 pac
= XMALLOC(MTYPE_TMP
, sizeof(struct test_peer_attr
));
1462 memcpy(pac
, pa
, sizeof(struct test_peer_attr
));
1464 pac
->afi
= pa
->families
[ii
].afi
;
1465 pac
->safi
= pa
->families
[ii
].safi
;
1466 listnode_add(pa_list
, pac
);
1472 for (ALL_LIST_ELEMENTS(pa_list
, node
, nnode
, pa
)) {
1476 /* Build test description string. */
1477 if (pa
->afi
&& pa
->safi
)
1478 desc
= asprintfrr(MTYPE_TMP
, "peer\\%s-%s\\%s",
1479 str_from_afi(pa
->afi
),
1480 str_from_safi(pa
->safi
), pa
->cmd
);
1482 desc
= asprintfrr(MTYPE_TMP
, "peer\\%s", pa
->cmd
);
1484 /* Initialize new test instance. */
1485 test
= test_new(desc
, pa
->o
.use_ibgp
, pa
->o
.use_iface_peer
);
1486 XFREE(MTYPE_TMP
, desc
);
1488 /* Execute tests and finish test instance. */
1489 test_peer_attr(test
, pa
);
1492 /* Print empty line as spacer. */
1495 /* Free memory used for peer-attr declaration. */
1496 XFREE(MTYPE_TMP
, pa
);
1499 list_delete(&pa_list
);