#include "bgpd/rfapi/rfapi_backend.h"
#endif
+#define OUT_SYMBOL_INFO "\u25ba"
+#define OUT_SYMBOL_OK "\u2714"
+#define OUT_SYMBOL_NOK "\u2716"
+
+#define TEST_ASSERT(T, C) \
+ do { \
+ if ((T)->state != TEST_SUCCESS || (C)) \
+ break; \
+ (T)->state = TEST_ASSERT_ERROR; \
+ (T)->error = str_printf("assertion failed: %s (%s:%d)", (#C), \
+ __FILE__, __LINE__); \
+ } while (0)
+
+#define TEST_ASSERT_EQ(T, A, B) \
+ do { \
+ if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
+ break; \
+ (T)->state = TEST_ASSERT_ERROR; \
+ (T)->error = str_printf( \
+ "assertion failed: %s[%d] == [%d]%s (%s:%d)", (#A), \
+ (A), (B), (#B), __FILE__, __LINE__); \
+ } while (0)
+
+#define TEST_HANDLER_MAX 5
+#define TEST_HANDLER(name) _test_handler_##name
+#define TEST_HANDLER_DECL(name) \
+ static void _test_handler_##name( \
+ struct test *test, struct test_peer_attr *pa, \
+ struct peer *peer, struct peer *group, bool peer_set, \
+ bool group_set)
+
+#define TEST_ATTR_HANDLER_DECL(name, attr, pval, gval) \
+ TEST_HANDLER_DECL(name) \
+ { \
+ if (peer_set) \
+ TEST_ASSERT_EQ(test, peer->attr, (pval)); \
+ else if (peer_group_active(peer) && group_set) \
+ TEST_ASSERT_EQ(test, peer->attr, (gval)); \
+ if (group_set) \
+ TEST_ASSERT_EQ(test, group->attr, (gval)); \
+ } \
+ TEST_HANDLER_DECL(name)
+
+#define TEST_STR_ATTR_HANDLER_DECL(name, attr, pval, gval) \
+ TEST_HANDLER_DECL(name) \
+ { \
+ if (peer_set) { \
+ TEST_ASSERT(test, peer->attr != NULL); \
+ TEST_ASSERT(test, !strcmp(peer->attr, (pval))); \
+ } else if (peer_group_active(peer) && group_set) { \
+ TEST_ASSERT(test, peer->attr != NULL); \
+ TEST_ASSERT(test, !strcmp(peer->attr, (gval))); \
+ } \
+ if (group_set) { \
+ TEST_ASSERT(test, group->attr != NULL); \
+ TEST_ASSERT(test, !strcmp(group->attr, (gval))); \
+ } \
+ } \
+ TEST_HANDLER_DECL(name)
+
+#define TEST_SU_ATTR_HANDLER_DECL(name, attr, pval, gval) \
+ TEST_HANDLER_DECL(name) \
+ { \
+ union sockunion su; \
+ if (peer_set) { \
+ str2sockunion(pval, &su); \
+ TEST_ASSERT(test, !sockunion_cmp(peer->attr, &su)); \
+ } else if (peer_group_active(peer) && group_set) { \
+ str2sockunion(gval, &su); \
+ TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
+ } \
+ if (group_set) { \
+ str2sockunion(gval, &su); \
+ TEST_ASSERT(test, !sockunion_cmp(group->attr, &su)); \
+ } \
+ } \
+ TEST_HANDLER_DECL(name)
+
/* Required variables to link in libbgp */
struct zebra_privs_t bgpd_privs = {0};
struct thread_master *master;
enum test_state {
TEST_SUCCESS,
+ TEST_SKIPPING,
TEST_COMMAND_ERROR,
TEST_CONFIG_ERROR,
TEST_ASSERT_ERROR,
+ TEST_CUSTOM_ERROR,
TEST_INTERNAL_ERROR,
};
+enum test_peer_attr_type {
+ PEER_AT_AF_FLAG = 0,
+ PEER_AT_AF_FILTER = 1,
+ PEER_AT_AF_CUSTOM = 2,
+ PEER_AT_GLOBAL_FLAG = 3,
+ PEER_AT_GLOBAL_CUSTOM = 4
+};
+
struct test {
enum test_state state;
char *desc;
struct bgp *bgp;
struct peer *peer;
struct peer_group *group;
+
+ struct {
+ bool use_ibgp;
+ bool use_iface_peer;
+ } o;
};
struct test_config {
int local_asn;
int peer_asn;
const char *peer_address;
+ const char *peer_interface;
const char *peer_group;
};
const char *peer_cmd;
const char *group_cmd;
- enum { PEER_AT_AF_FLAG = 0,
- PEER_AT_AF_FILTER = 1,
- PEER_AT_GLOBAL_FLAG = 2 } type;
+ enum test_peer_attr_type type;
union {
uint32_t flag;
struct {
} filter;
} u;
struct {
- bool invert;
+ bool invert_peer;
+ bool invert_group;
bool use_ibgp;
+ bool use_iface_peer;
+ bool skip_xfer_cases;
} o;
afi_t afi;
safi_t safi;
struct test_peer_family families[AFI_MAX * SAFI_MAX];
-};
-
-#define OUT_SYMBOL_INFO "\u25ba"
-#define OUT_SYMBOL_OK "\u2714"
-#define OUT_SYMBOL_NOK "\u2716"
-#define TEST_ASSERT_EQ(T, A, B) \
- do { \
- if ((T)->state != TEST_SUCCESS || ((A) == (B))) \
- break; \
- (T)->state = TEST_ASSERT_ERROR; \
- (T)->error = str_printf( \
- "assertion failed: %s[%d] == [%d]%s (%s:%d)", (#A), \
- (A), (B), (#B), __FILE__, __LINE__); \
- } while (0)
+ void (*handlers[TEST_HANDLER_MAX])(struct test *test,
+ struct test_peer_attr *pa,
+ struct peer *peer,
+ struct peer *group, bool peer_set,
+ bool group_set);
+};
static struct test_config cfg = {
.local_asn = 100,
.peer_asn = 200,
.peer_address = "1.1.1.1",
+ .peer_interface = "IP-TEST",
.peer_group = "PG-TEST",
};
{.afi = AFI_IP6, .safi = SAFI_MULTICAST},
};
+static char *str_vprintf(const char *fmt, va_list ap)
+{
+ int ret;
+ int buf_size = 0;
+ char *buf = NULL;
+ va_list apc;
+
+ while (1) {
+ va_copy(apc, ap);
+ ret = vsnprintf(buf, buf_size, fmt, apc);
+ va_end(apc);
+
+ if (ret >= 0 && ret < buf_size)
+ break;
+
+ if (ret >= 0)
+ buf_size = ret + 1;
+ else
+ buf_size *= 2;
+
+ buf = XREALLOC(MTYPE_TMP, buf, buf_size);
+ }
+
+ return buf;
+}
+
+static char *str_printf(const char *fmt, ...)
+{
+ char *buf;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buf = str_vprintf(fmt, ap);
+ va_end(ap);
+
+ return buf;
+}
+
+TEST_ATTR_HANDLER_DECL(advertisement_interval, v_routeadv, 10, 20);
+TEST_STR_ATTR_HANDLER_DECL(password, password, "FRR-Peer", "FRR-Group");
+TEST_ATTR_HANDLER_DECL(local_as, change_local_as, 1, 2);
+TEST_ATTR_HANDLER_DECL(timers_1, keepalive, 10, 20);
+TEST_ATTR_HANDLER_DECL(timers_2, holdtime, 30, 60);
+TEST_ATTR_HANDLER_DECL(addpath_types, addpath_type[pa->afi][pa->safi],
+ BGP_ADDPATH_ALL, BGP_ADDPATH_BEST_PER_AS);
+TEST_SU_ATTR_HANDLER_DECL(update_source_su, update_source, "255.255.255.1",
+ "255.255.255.2");
+TEST_STR_ATTR_HANDLER_DECL(update_source_if, update_if, "IF-PEER", "IF-GROUP");
+
+TEST_ATTR_HANDLER_DECL(allowas_in, allowas_in[pa->afi][pa->safi], 1, 2);
+TEST_STR_ATTR_HANDLER_DECL(default_originate_route_map,
+ default_rmap[pa->afi][pa->safi].name, "RM-PEER",
+ "RM-GROUP");
+TEST_STR_ATTR_HANDLER_DECL(
+ distribute_list,
+ filter[pa->afi][pa->safi].dlist[pa->u.filter.direct].name, "DL-PEER",
+ "DL-GROUP");
+TEST_STR_ATTR_HANDLER_DECL(
+ filter_list, filter[pa->afi][pa->safi].aslist[pa->u.filter.direct].name,
+ "FL-PEER", "FL-GROUP");
+TEST_ATTR_HANDLER_DECL(maximum_prefix, pmax[pa->afi][pa->safi], 10, 20);
+TEST_ATTR_HANDLER_DECL(maximum_prefix_threshold,
+ pmax_threshold[pa->afi][pa->safi], 1, 2);
+TEST_ATTR_HANDLER_DECL(maximum_prefix_restart, pmax_restart[pa->afi][pa->safi],
+ 100, 200);
+TEST_STR_ATTR_HANDLER_DECL(
+ prefix_list, filter[pa->afi][pa->safi].plist[pa->u.filter.direct].name,
+ "PL-PEER", "PL-GROUP");
+TEST_STR_ATTR_HANDLER_DECL(
+ route_map, filter[pa->afi][pa->safi].map[pa->u.filter.direct].name,
+ "RM-PEER", "RM-GROUP");
+TEST_STR_ATTR_HANDLER_DECL(unsuppress_map, filter[pa->afi][pa->safi].usmap.name,
+ "UM-PEER", "UM-GROUP");
+TEST_ATTR_HANDLER_DECL(weight, weight[pa->afi][pa->safi], 100, 200);
+
/* clang-format off */
static struct test_peer_attr test_peer_attrs[] = {
+ /* Peer Attributes */
+ {
+ .cmd = "advertisement-interval",
+ .peer_cmd = "advertisement-interval 10",
+ .group_cmd = "advertisement-interval 20",
+ .u.flag = PEER_FLAG_ROUTEADV,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(advertisement_interval),
+ },
+ {
+ .cmd = "capability dynamic",
+ .u.flag = PEER_FLAG_DYNAMIC_CAPABILITY,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "capability extended-nexthop",
+ .u.flag = PEER_FLAG_CAPABILITY_ENHE,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "capability extended-nexthop",
+ .u.flag = PEER_FLAG_CAPABILITY_ENHE,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .o.invert_peer = true,
+ .o.use_iface_peer = true,
+ },
+ {
+ .cmd = "description",
+ .peer_cmd = "description FRR Peer",
+ .group_cmd = "description FRR Group",
+ .type = PEER_AT_GLOBAL_CUSTOM,
+ },
+ {
+ .cmd = "disable-connected-check",
+ .u.flag = PEER_FLAG_DISABLE_CONNECTED_CHECK,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "dont-capability-negotiate",
+ .u.flag = PEER_FLAG_DONT_CAPABILITY,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "enforce-first-as",
+ .u.flag = PEER_FLAG_ENFORCE_FIRST_AS,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "local-as",
+ .peer_cmd = "local-as 1",
+ .group_cmd = "local-as 2",
+ .u.flag = PEER_FLAG_LOCAL_AS,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(local_as),
+ },
+ {
+ .cmd = "local-as 1 no-prepend",
+ .u.flag = PEER_FLAG_LOCAL_AS | PEER_FLAG_LOCAL_AS_NO_PREPEND,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "local-as 1 no-prepend replace-as",
+ .u.flag = PEER_FLAG_LOCAL_AS | PEER_FLAG_LOCAL_AS_REPLACE_AS,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "override-capability",
+ .u.flag = PEER_FLAG_OVERRIDE_CAPABILITY,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "passive",
+ .u.flag = PEER_FLAG_PASSIVE,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "password",
+ .peer_cmd = "password FRR-Peer",
+ .group_cmd = "password FRR-Group",
+ .u.flag = PEER_FLAG_PASSWORD,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(password),
+ },
+ {
+ .cmd = "shutdown",
+ .u.flag = PEER_FLAG_SHUTDOWN,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "strict-capability-match",
+ .u.flag = PEER_FLAG_STRICT_CAP_MATCH,
+ .type = PEER_AT_GLOBAL_FLAG,
+ },
+ {
+ .cmd = "timers",
+ .peer_cmd = "timers 10 30",
+ .group_cmd = "timers 20 60",
+ .u.flag = PEER_FLAG_TIMER,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(timers_1),
+ .handlers[1] = TEST_HANDLER(timers_2),
+ },
{
- .cmd = "addpath-tx-all-paths",
- .u.flag = PEER_FLAG_ADDPATH_TX_ALL_PATHS,
+ .cmd = "timers connect",
+ .peer_cmd = "timers connect 10",
+ .group_cmd = "timers connect 20",
+ .u.flag = PEER_FLAG_TIMER_CONNECT,
+ .type = PEER_AT_GLOBAL_FLAG,
},
{
- .cmd = "addpath-tx-bestpath-per-AS",
- .u.flag = PEER_FLAG_ADDPATH_TX_BESTPATH_PER_AS,
+ .cmd = "update-source",
+ .peer_cmd = "update-source 255.255.255.1",
+ .group_cmd = "update-source 255.255.255.2",
+ .u.flag = PEER_FLAG_UPDATE_SOURCE,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(update_source_su),
+ },
+ {
+ .cmd = "update-source",
+ .peer_cmd = "update-source IF-PEER",
+ .group_cmd = "update-source IF-GROUP",
+ .u.flag = PEER_FLAG_UPDATE_SOURCE,
+ .type = PEER_AT_GLOBAL_FLAG,
+ .handlers[0] = TEST_HANDLER(update_source_if),
+ },
+
+ /* Address Family Attributes */
+ {
+ .cmd = "addpath",
+ .peer_cmd = "addpath-tx-all-paths",
+ .group_cmd = "addpath-tx-bestpath-per-AS",
+ .type = PEER_AT_AF_CUSTOM,
+ .handlers[0] = TEST_HANDLER(addpath_types),
},
{
.cmd = "allowas-in",
.peer_cmd = "allowas-in 1",
.group_cmd = "allowas-in 2",
.u.flag = PEER_FLAG_ALLOWAS_IN,
+ .handlers[0] = TEST_HANDLER(allowas_in),
},
{
.cmd = "allowas-in origin",
.peer_cmd = "default-originate route-map RM-PEER",
.group_cmd = "default-originate route-map RM-GROUP",
.u.flag = PEER_FLAG_DEFAULT_ORIGINATE,
+ .handlers[0] = TEST_HANDLER(default_originate_route_map),
+ },
+ {
+ .cmd = "distribute-list",
+ .peer_cmd = "distribute-list DL-PEER in",
+ .group_cmd = "distribute-list DL-GROUP in",
+ .type = PEER_AT_AF_FILTER,
+ .u.filter.flag = PEER_FT_DISTRIBUTE_LIST,
+ .u.filter.direct = FILTER_IN,
+ .handlers[0] = TEST_HANDLER(distribute_list),
+ },
+ {
+ .cmd = "distribute-list",
+ .peer_cmd = "distribute-list DL-PEER out",
+ .group_cmd = "distribute-list DL-GROUP out",
+ .type = PEER_AT_AF_FILTER,
+ .u.filter.flag = PEER_FT_DISTRIBUTE_LIST,
+ .u.filter.direct = FILTER_OUT,
+ .handlers[0] = TEST_HANDLER(distribute_list),
},
{
.cmd = "filter-list",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_FILTER_LIST,
.u.filter.direct = FILTER_IN,
+ .handlers[0] = TEST_HANDLER(filter_list),
},
{
.cmd = "filter-list",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_FILTER_LIST,
.u.filter.direct = FILTER_OUT,
+ .handlers[0] = TEST_HANDLER(filter_list),
},
{
.cmd = "maximum-prefix",
.peer_cmd = "maximum-prefix 10",
.group_cmd = "maximum-prefix 20",
.u.flag = PEER_FLAG_MAX_PREFIX,
+ .handlers[0] = TEST_HANDLER(maximum_prefix),
},
{
.cmd = "maximum-prefix",
.peer_cmd = "maximum-prefix 10 restart 100",
.group_cmd = "maximum-prefix 20 restart 200",
.u.flag = PEER_FLAG_MAX_PREFIX,
+ .handlers[0] = TEST_HANDLER(maximum_prefix),
+ .handlers[1] = TEST_HANDLER(maximum_prefix_restart),
},
{
.cmd = "maximum-prefix",
.peer_cmd = "maximum-prefix 10 1 restart 100",
.group_cmd = "maximum-prefix 20 2 restart 200",
.u.flag = PEER_FLAG_MAX_PREFIX,
+ .handlers[0] = TEST_HANDLER(maximum_prefix),
+ .handlers[1] = TEST_HANDLER(maximum_prefix_threshold),
+ .handlers[2] = TEST_HANDLER(maximum_prefix_restart),
},
{
.cmd = "maximum-prefix",
.peer_cmd = "maximum-prefix 10 warning-only",
.group_cmd = "maximum-prefix 20 warning-only",
.u.flag = PEER_FLAG_MAX_PREFIX | PEER_FLAG_MAX_PREFIX_WARNING,
+ .handlers[0] = TEST_HANDLER(maximum_prefix),
},
{
.cmd = "maximum-prefix",
.peer_cmd = "maximum-prefix 10 1 warning-only",
.group_cmd = "maximum-prefix 20 2 warning-only",
.u.flag = PEER_FLAG_MAX_PREFIX | PEER_FLAG_MAX_PREFIX_WARNING,
+ .handlers[0] = TEST_HANDLER(maximum_prefix),
+ .handlers[1] = TEST_HANDLER(maximum_prefix_threshold),
},
{
.cmd = "next-hop-self",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_PREFIX_LIST,
.u.filter.direct = FILTER_IN,
+ .handlers[0] = TEST_HANDLER(prefix_list),
},
{
.cmd = "prefix-list",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_PREFIX_LIST,
.u.filter.direct = FILTER_OUT,
+ .handlers[0] = TEST_HANDLER(prefix_list),
},
{
.cmd = "remove-private-AS",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_ROUTE_MAP,
.u.filter.direct = FILTER_IN,
+ .handlers[0] = TEST_HANDLER(route_map),
},
{
.cmd = "route-map",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_ROUTE_MAP,
.u.filter.direct = FILTER_OUT,
+ .handlers[0] = TEST_HANDLER(route_map),
},
{
.cmd = "route-reflector-client",
.u.flag = PEER_FLAG_REFLECTOR_CLIENT,
.o.use_ibgp = true,
+ .o.skip_xfer_cases = true,
},
{
.cmd = "route-server-client",
{
.cmd = "send-community",
.u.flag = PEER_FLAG_SEND_COMMUNITY,
- .o.invert = true,
+ .o.invert_peer = true,
+ .o.invert_group = true,
},
{
.cmd = "send-community extended",
.u.flag = PEER_FLAG_SEND_EXT_COMMUNITY,
- .o.invert = true,
+ .o.invert_peer = true,
+ .o.invert_group = true,
},
{
.cmd = "send-community large",
.u.flag = PEER_FLAG_SEND_LARGE_COMMUNITY,
- .o.invert = true,
+ .o.invert_peer = true,
+ .o.invert_group = true,
},
{
.cmd = "soft-reconfiguration inbound",
.type = PEER_AT_AF_FILTER,
.u.filter.flag = PEER_FT_UNSUPPRESS_MAP,
.u.filter.direct = 0,
+ .handlers[0] = TEST_HANDLER(unsuppress_map),
},
{
.cmd = "weight",
.peer_cmd = "weight 100",
.group_cmd = "weight 200",
.u.flag = PEER_FLAG_WEIGHT,
+ .handlers[0] = TEST_HANDLER(weight),
},
{NULL}
};
/* clang-format on */
-static char *str_vprintf(const char *fmt, va_list ap)
-{
- int ret;
- int buf_size = 0;
- char *buf = NULL;
- va_list apc;
-
- while (1) {
- va_copy(apc, ap);
- ret = vsnprintf(buf, buf_size, fmt, apc);
- va_end(apc);
-
- if (ret >= 0 && ret < buf_size)
- break;
-
- if (ret >= 0)
- buf_size = ret + 1;
- else
- buf_size *= 2;
-
- buf = XREALLOC(MTYPE_TMP, buf, buf_size);
- }
-
- return buf;
-}
-
-static char *str_printf(const char *fmt, ...)
-{
- char *buf;
- va_list ap;
-
- va_start(ap, fmt);
- buf = str_vprintf(fmt, ap);
- va_end(ap);
-
- return buf;
-}
-
static const char *str_from_afi(afi_t afi)
{
switch (afi) {
}
}
+static const char *str_from_attr_type(enum test_peer_attr_type at)
+{
+ switch (at) {
+ case PEER_AT_GLOBAL_FLAG:
+ return "peer-flag";
+ case PEER_AT_AF_FLAG:
+ return "af-flag";
+ case PEER_AT_AF_FILTER:
+ return "af-filter";
+ case PEER_AT_GLOBAL_CUSTOM:
+ case PEER_AT_AF_CUSTOM:
+ return "custom";
+ default:
+ return NULL;
+ }
+}
+
+static bool is_attr_type_global(enum test_peer_attr_type at)
+{
+ return at == PEER_AT_GLOBAL_FLAG || at == PEER_AT_GLOBAL_CUSTOM;
+}
+
+static void test_log(struct test *test, const char *fmt, ...)
+{
+ va_list ap;
+
+ /* Skip logging if test instance has previously failed. */
+ if (test->state != TEST_SUCCESS)
+ return;
+
+ /* Store formatted log message. */
+ va_start(ap, fmt);
+ listnode_add(test->log, str_vprintf(fmt, ap));
+ va_end(ap);
+}
+
static void test_execute(struct test *test, const char *fmt, ...)
{
int ret;
va_end(ap);
}
-static struct test *test_new(const char *desc, bool use_ibgp)
+static void test_initialize(struct test *test)
{
- struct test *test;
union sockunion su;
- test = XCALLOC(MTYPE_TMP, sizeof(struct test));
- test->state = TEST_SUCCESS;
- test->desc = XSTRDUP(MTYPE_TMP, desc);
- test->log = list_new();
+ /* Skip execution if test instance has previously failed. */
+ if (test->state != TEST_SUCCESS)
+ return;
- test->vty = vty_new();
- test->vty->type = VTY_TERM;
- test->vty->node = CONFIG_NODE;
+ /* Log message about (re)-initialization */
+ test_log(test, "prepare: %sinitialize bgp test environment",
+ test->bgp ? "re-" : "");
/* Attempt gracefully to purge previous BGP configuration. */
test_execute(test, "no router bgp");
test_execute(test, "router bgp %d", cfg.local_asn);
test_execute(test, "no bgp default ipv4-unicast");
test_execute(test, "neighbor %s peer-group", cfg.peer_group);
- test_execute(test, "neighbor %s remote-as %d", cfg.peer_address,
- use_ibgp ? cfg.local_asn : cfg.peer_asn);
+ if (test->o.use_iface_peer) {
+ test_execute(test, "neighbor %s interface", cfg.peer_interface);
+ test_execute(test, "neighbor %s remote-as %d",
+ cfg.peer_interface,
+ test->o.use_ibgp ? cfg.local_asn : cfg.peer_asn);
+ } else {
+ test_execute(test, "neighbor %s remote-as %d", cfg.peer_address,
+ test->o.use_ibgp ? cfg.local_asn : cfg.peer_asn);
+ }
+
if (test->state != TEST_SUCCESS)
- return test;
+ return;
/* Fetch default BGP instance. */
test->bgp = bgp_get_default();
test->state = TEST_INTERNAL_ERROR;
test->error =
str_printf("could not retrieve default bgp instance");
- return test;
+ return;
}
/* Fetch peer instance. */
- str2sockunion(cfg.peer_address, &su);
- test->peer = peer_lookup(test->bgp, &su);
+ if (test->o.use_iface_peer) {
+ test->peer =
+ peer_lookup_by_conf_if(test->bgp, cfg.peer_interface);
+ } else {
+ str2sockunion(cfg.peer_address, &su);
+ test->peer = peer_lookup(test->bgp, &su);
+ }
if (!test->peer) {
test->state = TEST_INTERNAL_ERROR;
test->error = str_printf(
"could not retrieve instance of bgp peer [%s]",
cfg.peer_address);
- return test;
+ return;
}
/* Fetch peer-group instance. */
test->error = str_printf(
"could not retrieve instance of bgp peer-group [%s]",
cfg.peer_group);
- return test;
+ return;
}
+}
- return test;
-};
-
-static void test_log(struct test *test, const char *fmt, ...)
+static struct test *test_new(const char *desc, bool use_ibgp,
+ bool use_iface_peer)
{
- va_list ap;
+ struct test *test;
- /* Skip logging if test instance has previously failed. */
- if (test->state != TEST_SUCCESS)
- return;
+ test = XCALLOC(MTYPE_TMP, sizeof(struct test));
+ test->state = TEST_SUCCESS;
+ test->desc = XSTRDUP(MTYPE_TMP, desc);
+ test->log = list_new();
+ test->o.use_ibgp = use_ibgp;
+ test->o.use_iface_peer = use_iface_peer;
- /* Store formatted log message. */
- va_start(ap, fmt);
- listnode_add(test->log, str_vprintf(fmt, ap));
- va_end(ap);
-}
+ test->vty = vty_new();
+ test->vty->type = VTY_TERM;
+ test->vty->node = CONFIG_NODE;
+
+ test_initialize(test);
+
+ return test;
+};
static void test_finish(struct test *test)
{
test->vty = NULL;
}
if (test->log)
- list_delete_and_null(&test->log);
+ list_delete(&test->log);
if (test->desc)
XFREE(MTYPE_TMP, test->desc);
if (test->error)
XFREE(MTYPE_TMP, test);
}
-static void test_af_flags(struct test *test, struct peer *peer,
- struct test_peer_attr *attr, bool exp_val,
- bool exp_ovrd)
+static void test_peer_flags(struct test *test, struct test_peer_attr *pa,
+ struct peer *peer, bool exp_val, bool exp_ovrd)
{
bool exp_inv, cur_val, cur_ovrd, cur_inv;
- /* Flip expected values for inverted flags. */
- exp_inv = attr->o.invert;
+ /* Skip execution if test instance has previously failed. */
+ if (test->state != TEST_SUCCESS)
+ return;
+
+ /* Detect if flag is meant to be inverted. */
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
+ exp_inv = pa->o.invert_group;
+ else
+ exp_inv = pa->o.invert_peer;
+
+ /* Flip expected value if flag is inverted. */
exp_val ^= exp_inv;
/* Fetch current state of value, override and invert flags. */
- cur_val = !!CHECK_FLAG(peer->af_flags[attr->afi][attr->safi],
- attr->u.flag);
- cur_ovrd = !!CHECK_FLAG(peer->af_flags_override[attr->afi][attr->safi],
- attr->u.flag);
- cur_inv = !!CHECK_FLAG(peer->af_flags_invert[attr->afi][attr->safi],
- attr->u.flag);
+ if (pa->type == PEER_AT_GLOBAL_FLAG) {
+ cur_val = !!CHECK_FLAG(peer->flags, pa->u.flag);
+ cur_ovrd = !!CHECK_FLAG(peer->flags_override, pa->u.flag);
+ cur_inv = !!CHECK_FLAG(peer->flags_invert, pa->u.flag);
+ } else /* if (pa->type == PEER_AT_AF_FLAG) */ {
+ cur_val = !!CHECK_FLAG(peer->af_flags[pa->afi][pa->safi],
+ pa->u.flag);
+ cur_ovrd = !!CHECK_FLAG(
+ peer->af_flags_override[pa->afi][pa->safi], pa->u.flag);
+ cur_inv = !!CHECK_FLAG(peer->af_flags_invert[pa->afi][pa->safi],
+ pa->u.flag);
+ }
/* Assert expected flag states. */
TEST_ASSERT_EQ(test, cur_val, exp_val);
TEST_ASSERT_EQ(test, cur_inv, exp_inv);
}
-static void test_af_filter(struct test *test, struct peer *peer,
- struct test_peer_attr *attr, bool exp_state,
- bool exp_ovrd)
+static void test_af_filter(struct test *test, struct test_peer_attr *pa,
+ struct peer *peer, bool exp_state, bool exp_ovrd)
{
bool cur_ovrd;
struct bgp_filter *filter;
+ /* Skip execution if test instance has previously failed. */
+ if (test->state != TEST_SUCCESS)
+ return;
+
/* Fetch and assert current state of override flag. */
- cur_ovrd = !!CHECK_FLAG(peer->filter_override[attr->afi][attr->safi]
- [attr->u.filter.direct],
- attr->u.filter.flag);
+ cur_ovrd = !!CHECK_FLAG(
+ peer->filter_override[pa->afi][pa->safi][pa->u.filter.direct],
+ pa->u.filter.flag);
TEST_ASSERT_EQ(test, cur_ovrd, exp_ovrd);
/* Assert that map/list matches expected state (set/unset). */
- filter = &peer->filter[attr->afi][attr->safi];
+ filter = &peer->filter[pa->afi][pa->safi];
- switch (attr->u.filter.flag) {
+ switch (pa->u.filter.flag) {
case PEER_FT_DISTRIBUTE_LIST:
TEST_ASSERT_EQ(test,
- !!(filter->dlist[attr->u.filter.direct].name),
+ !!(filter->dlist[pa->u.filter.direct].name),
exp_state);
break;
case PEER_FT_FILTER_LIST:
TEST_ASSERT_EQ(test,
- !!(filter->aslist[attr->u.filter.direct].name),
+ !!(filter->aslist[pa->u.filter.direct].name),
exp_state);
break;
case PEER_FT_PREFIX_LIST:
TEST_ASSERT_EQ(test,
- !!(filter->plist[attr->u.filter.direct].name),
+ !!(filter->plist[pa->u.filter.direct].name),
exp_state);
break;
case PEER_FT_ROUTE_MAP:
- TEST_ASSERT_EQ(test,
- !!(filter->map[attr->u.filter.direct].name),
+ TEST_ASSERT_EQ(test, !!(filter->map[pa->u.filter.direct].name),
exp_state);
break;
case PEER_FT_UNSUPPRESS_MAP:
}
}
+static void test_custom(struct test *test, struct test_peer_attr *pa,
+ struct peer *peer, struct peer *group, bool peer_set,
+ bool group_set)
+{
+ int i;
+ char *handler_error;
+
+ for (i = 0; i < TEST_HANDLER_MAX; i++) {
+ /* Skip execution if test instance has previously failed. */
+ if (test->state != TEST_SUCCESS)
+ return;
+
+ /* Skip further execution if handler is undefined. */
+ if (!pa->handlers[i])
+ return;
+
+ /* Execute custom handler. */
+ pa->handlers[i](test, pa, peer, group, peer_set, group_set);
+ if (test->state != TEST_SUCCESS) {
+ test->state = TEST_CUSTOM_ERROR;
+ handler_error = test->error;
+ test->error = str_printf("custom handler failed: %s",
+ handler_error);
+ XFREE(MTYPE_TMP, handler_error);
+ }
+ }
+}
+
+
+static void test_process(struct test *test, struct test_peer_attr *pa,
+ struct peer *peer, struct peer *group, bool peer_set,
+ bool group_set)
+{
+ switch (pa->type) {
+ case PEER_AT_GLOBAL_FLAG:
+ case PEER_AT_AF_FLAG:
+ test_peer_flags(
+ test, pa, peer,
+ peer_set || (peer_group_active(peer) && group_set),
+ peer_set);
+ test_peer_flags(test, pa, group, group_set, false);
+ break;
+
+ case PEER_AT_AF_FILTER:
+ test_af_filter(
+ test, pa, peer,
+ peer_set || (peer_group_active(peer) && group_set),
+ peer_set);
+ test_af_filter(test, pa, group, group_set, false);
+ break;
+
+ case PEER_AT_GLOBAL_CUSTOM:
+ case PEER_AT_AF_CUSTOM:
+ /*
+ * Do nothing here - a custom handler can be executed, but this
+ * is not required. This will allow defining peer attributes
+ * which shall not be checked for flag/filter/other internal
+ * states.
+ */
+ break;
+
+ default:
+ test->state = TEST_INTERNAL_ERROR;
+ test->error =
+ str_printf("invalid attribute type: %d", pa->type);
+ break;
+ }
+
+ /* Attempt to call a custom handler if set for further processing. */
+ test_custom(test, pa, peer, group, peer_set, group_set);
+}
+
static void test_peer_attr(struct test *test, struct test_peer_attr *pa)
{
int tc = 1;
const char *type;
- const char *ec = pa->o.invert ? "no " : "";
- const char *dc = pa->o.invert ? "" : "no ";
+ const char *ecp = pa->o.invert_peer ? "no " : "";
+ const char *dcp = pa->o.invert_peer ? "" : "no ";
+ const char *ecg = pa->o.invert_group ? "no " : "";
+ const char *dcg = pa->o.invert_group ? "" : "no ";
const char *peer_cmd = pa->peer_cmd ?: pa->cmd;
const char *group_cmd = pa->group_cmd ?: pa->cmd;
struct peer *p = test->peer;
struct peer_group *g = test->group;
- if (pa->type == PEER_AT_AF_FLAG)
- type = "af-flag";
- else /* if (pa->type == PEER_AT_AF_FILTER) */
- type = "af-filter";
+ /* Determine type and if test is address-family relevant */
+ type = str_from_attr_type(pa->type);
+ if (!type) {
+ test->state = TEST_INTERNAL_ERROR;
+ test->error =
+ str_printf("invalid attribute type: %d", pa->type);
+ return;
+ }
- /* Test Case: Switch active address-family. */
- if (pa->type == PEER_AT_AF_FLAG || pa->type == PEER_AT_AF_FILTER) {
+ /*
+ * =====================================================================
+ * Test Case Suite 1: Config persistence after adding peer to group
+ *
+ * Example: If a peer attribute has value [1] and a group attribute has
+ * value [2], the peer attribute value should be persisted when the peer
+ * gets added to the peer-group.
+ *
+ * This test suite is meant to test the group2peer functions which can
+ * be found inside bgpd/bgpd.c, which are related to initial peer-group
+ * inheritance.
+ * =====================================================================
+ */
+
+ /* Test Preparation: Switch and activate address-family. */
+ if (!is_attr_type_global(pa->type)) {
test_log(test, "prepare: switch address-family to [%s]",
afi_safi_print(pa->afi, pa->safi));
test_execute(test, "address-family %s %s",
str_from_afi(pa->afi), str_from_safi(pa->safi));
+ test_execute(test, "neighbor %s activate", g->name);
+ test_execute(test, "neighbor %s activate", p->host);
}
+ /* Skip peer-group to peer transfer test cases if requested. */
+ if (pa->o.skip_xfer_cases && test->state == TEST_SUCCESS)
+ test->state = TEST_SKIPPING;
+
/* Test Case: Set flag on BGP peer. */
test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, peer_cmd,
p->host);
- test_execute(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
+ test_execute(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, false, false);
- }
+ test_process(test, pa, p, g->conf, true, false);
+
+ /* Test Case: Set flag on BGP peer-group. */
+ test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, group_cmd,
+ g->name);
+ test_execute(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, true, true);
/* Test Case: Add BGP peer to peer-group. */
test_log(test, "case %02d: add peer [%s] to group [%s]", tc++, p->host,
g->name);
test_execute(test, "neighbor %s peer-group %s", p->host, g->name);
- test_config_present(test, "neighbor %s peer-group %s", p->host,
- g->name);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
+ test_config_present(test, "neighbor %s %speer-group %s", p->host,
+ p->conf_if ? "interface " : "", g->name);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, true, true);
+
+ /* Test Case: Unset flag on BGP peer-group. */
+ test_log(test, "case %02d: unset %s [%s] on [%s]", tc++, type,
+ group_cmd, g->name);
+ test_execute(test, "%sneighbor %s %s", dcg, g->name, group_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, false, false);
+ test_process(test, pa, p, g->conf, true, false);
+
+ /*
+ * =====================================================================
+ * Test Case Suite 2: Config inheritance after adding peer to group
+ *
+ * Example: If a peer attribute has not been set and a group attribute
+ * has a value of [2], the group attribute should be inherited to the
+ * peer without flagging the newly set value as overridden.
+ *
+ * This test suite is meant to test the group2peer functions which can
+ * be found inside bgpd/bgpd.c, which are related to initial peer-group
+ * inheritance.
+ * =====================================================================
+ */
+
+ /* Test Preparation: Re-initialize test environment. */
+ test_initialize(test);
+ p = test->peer;
+ g = test->group;
+
+ /* Test Preparation: Switch and activate address-family. */
+ if (!is_attr_type_global(pa->type)) {
+ test_log(test, "prepare: switch address-family to [%s]",
+ afi_safi_print(pa->afi, pa->safi));
+ test_execute(test, "address-family %s %s",
+ str_from_afi(pa->afi), str_from_safi(pa->safi));
+ test_execute(test, "neighbor %s activate", g->name);
+ test_execute(test, "neighbor %s activate", p->host);
+ }
+
+ /* Test Case: Set flag on BGP peer-group. */
+ test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, group_cmd,
+ g->name);
+ test_execute(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_config_absent(test, "neighbor %s %s", p->host, pa->cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, false, true);
+
+ /* Test Case: Add BGP peer to peer-group. */
+ test_log(test, "case %02d: add peer [%s] to group [%s]", tc++, p->host,
+ g->name);
+ test_execute(test, "neighbor %s peer-group %s", p->host, g->name);
+ test_config_present(test, "neighbor %s %speer-group %s", p->host,
+ p->conf_if ? "interface " : "", g->name);
+ test_config_absent(test, "neighbor %s %s", p->host, pa->cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, false, true);
+
+ /* Stop skipping test cases if previously enabled. */
+ if (pa->o.skip_xfer_cases && test->state == TEST_SKIPPING)
+ test->state = TEST_SUCCESS;
+
+ /*
+ * =====================================================================
+ * Test Case Suite 3: Miscellaneous flag checks
+ *
+ * This test suite does not focus on initial peer-group inheritance and
+ * instead executes various different commands to set/unset attributes
+ * on both peer- and group-level. These checks should always be executed
+ * and must pass.
+ * =====================================================================
+ */
+
+ /* Test Preparation: Re-initialize test environment. */
+ test_initialize(test);
+ p = test->peer;
+ g = test->group;
+
+ /* Test Preparation: Switch and activate address-family. */
+ if (!is_attr_type_global(pa->type)) {
+ test_log(test, "prepare: switch address-family to [%s]",
+ afi_safi_print(pa->afi, pa->safi));
+ test_execute(test, "address-family %s %s",
+ str_from_afi(pa->afi), str_from_safi(pa->safi));
+ test_execute(test, "neighbor %s activate", g->name);
+ test_execute(test, "neighbor %s activate", p->host);
}
+ /* Test Case: Set flag on BGP peer. */
+ test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, peer_cmd,
+ p->host);
+ test_execute(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
+ test_process(test, pa, p, g->conf, true, false);
+
+ /* Test Case: Add BGP peer to peer-group. */
+ test_log(test, "case %02d: add peer [%s] to group [%s]", tc++, p->host,
+ g->name);
+ test_execute(test, "neighbor %s peer-group %s", p->host, g->name);
+ test_config_present(test, "neighbor %s %speer-group %s", p->host,
+ p->conf_if ? "interface " : "", g->name);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
+ test_process(test, pa, p, g->conf, true, false);
+
/* Test Case: Re-add BGP peer to peer-group. */
test_log(test, "case %02d: re-add peer [%s] to group [%s]", tc++,
p->host, g->name);
test_execute(test, "neighbor %s peer-group %s", p->host, g->name);
- test_config_present(test, "neighbor %s peer-group %s", p->host,
- g->name);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
+ test_config_present(test, "neighbor %s %speer-group %s", p->host,
+ p->conf_if ? "interface " : "", g->name);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, false, false);
- }
+ test_process(test, pa, p, g->conf, true, false);
/* Test Case: Set flag on BGP peer-group. */
test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, group_cmd,
g->name);
- test_execute(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, true, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, true, false);
- }
+ test_execute(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, true, true);
/* Test Case: Unset flag on BGP peer-group. */
test_log(test, "case %02d: unset %s [%s] on [%s]", tc++, type,
group_cmd, g->name);
- test_execute(test, "%sneighbor %s %s", dc, g->name, group_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
+ test_execute(test, "%sneighbor %s %s", dcg, g->name, group_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, false, false);
- }
+ test_process(test, pa, p, g->conf, true, false);
/* Test Case: Set flag on BGP peer-group. */
test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, group_cmd,
g->name);
- test_execute(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, true, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, true, false);
- }
+ test_execute(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, true, true);
/* Test Case: Re-set flag on BGP peer. */
test_log(test, "case %02d: re-set %s [%s] on [%s]", tc++, type,
peer_cmd, p->host);
- test_execute(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, true, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, true, false);
- }
+ test_execute(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, true, true);
/* Test Case: Unset flag on BGP peer. */
test_log(test, "case %02d: unset %s [%s] on [%s]", tc++, type, peer_cmd,
p->host);
- test_execute(test, "%sneighbor %s %s", dc, p->host, peer_cmd);
+ test_execute(test, "%sneighbor %s %s", dcp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", p->host, pa->cmd);
- test_config_present(test, "%sneighbor %s %s", ec, g->name, group_cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, false);
- test_af_flags(test, g->conf, pa, true, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, false);
- test_af_filter(test, g->conf, pa, true, false);
- }
+ test_config_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd);
+ test_process(test, pa, p, g->conf, false, true);
/* Test Case: Unset flag on BGP peer-group. */
test_log(test, "case %02d: unset %s [%s] on [%s]", tc++, type,
group_cmd, g->name);
- test_execute(test, "%sneighbor %s %s", dc, g->name, group_cmd);
+ test_execute(test, "%sneighbor %s %s", dcg, g->name, group_cmd);
test_config_absent(test, "neighbor %s %s", p->host, pa->cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, false, false);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, false, false);
- test_af_filter(test, g->conf, pa, false, false);
- }
+ test_process(test, pa, p, g->conf, false, false);
/* Test Case: Set flag on BGP peer. */
test_log(test, "case %02d: set %s [%s] on [%s]", tc++, type, peer_cmd,
p->host);
- test_execute(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
- test_config_present(test, "%sneighbor %s %s", ec, p->host, peer_cmd);
+ test_execute(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
+ test_config_present(test, "%sneighbor %s %s", ecp, p->host, peer_cmd);
test_config_absent(test, "neighbor %s %s", g->name, pa->cmd);
- if (pa->type == PEER_AT_AF_FLAG) {
- test_af_flags(test, p, pa, true, true);
- test_af_flags(test, g->conf, pa, false, false);
- } else if (pa->type == PEER_AT_AF_FILTER) {
- test_af_filter(test, p, pa, true, true);
- test_af_filter(test, g->conf, pa, false, false);
- }
+ test_process(test, pa, p, g->conf, true, false);
}
static void bgp_startup(void)
zprivs_init(&bgpd_privs);
master = thread_master_create(NULL);
+ yang_init();
+ nb_init(master, NULL, 0);
bgp_master_init(master);
bgp_option_set(BGP_OPT_NO_LISTEN);
- vrf_init(NULL, NULL, NULL, NULL);
- bgp_init();
+ vrf_init(NULL, NULL, NULL, NULL, NULL);
+ bgp_init(0);
bgp_pthreads_run();
}
bgp_zebra_destroy();
bf_free(bm->rd_idspace);
- list_delete_and_null(&bm->bgp);
+ list_delete(&bm->bgp);
memset(bm, 0, sizeof(*bm));
vty_terminate();
cmd_terminate();
+ nb_terminate();
+ yang_terminate();
zprivs_terminate(&bgpd_privs);
thread_master_free(master);
master = NULL;
pa = &test_peer_attrs[i++];
/* Just copy the peer attribute structure for global flags. */
- if (pa->type == PEER_AT_GLOBAL_FLAG) {
+ if (is_attr_type_global(pa->type)) {
pac = XMALLOC(MTYPE_TMP, sizeof(struct test_peer_attr));
memcpy(pac, pa, sizeof(struct test_peer_attr));
listnode_add(pa_list, pac);
desc = str_printf("peer\\%s", pa->cmd);
/* Initialize new test instance. */
- test = test_new(desc, pa->o.use_ibgp);
+ test = test_new(desc, pa->o.use_ibgp, pa->o.use_iface_peer);
XFREE(MTYPE_TMP, desc);
/* Execute tests and finish test instance. */
XFREE(MTYPE_TMP, pa);
}
- list_delete_and_null(&pa_list);
+ list_delete(&pa_list);
bgp_shutdown();
return 0;