From e7103a9644f32a70a10be8f6372aa9084aa33c2f Mon Sep 17 00:00:00 2001 From: Pascal Mathis Date: Tue, 12 Jun 2018 17:09:49 +0200 Subject: [PATCH] bgpd: Fix AF-attribute overrides when binding peer The current implementation of the overrides for peer address-family attributes suffered a bug, which caused all peer-specific attributes to be lost when the peer was added to a peer-group which already had that specific address-family active. This commit extends the *peer_group2peer_config_copy_af* function to respect overridden flags properly. Additionally, the arguments of the macros *PEER_ATTR_INHERIT* and *PEER_STR_ATTR_INHERIT* have been reordered to be more consistent and easy to read. This commit also adds further test cases to the BGP peer attributes test suite, so that this kind of error is being caught in future commits. The missing AF-attribute *distribute-list* has also been added to the test suite. Signed-off-by: Pascal Mathis --- bgpd/bgpd.c | 239 ++++++++++++++++------------------- bgpd/bgpd.h | 9 +- tests/bgpd/test_peer_attr.c | 148 +++++++++++++++++++--- tests/bgpd/test_peer_attr.py | 8 ++ 4 files changed, 251 insertions(+), 153 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 9c84b3042f..f332c7c9bb 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1813,141 +1813,111 @@ static void peer_group2peer_config_copy_af(struct peer_group *group, { int in = FILTER_IN; int out = FILTER_OUT; + uint32_t pflags_ovrd; + uint8_t *pfilter_ovrd; struct peer *conf; - struct bgp_filter *pfilter; - struct bgp_filter *gfilter; conf = group->conf; - pfilter = &peer->filter[afi][safi]; - gfilter = &conf->filter[afi][safi]; + pflags_ovrd = peer->af_flags_override[afi][safi]; + pfilter_ovrd = &peer->filter_override[afi][safi][in]; /* peer af_flags apply */ - peer->af_flags[afi][safi] = conf->af_flags[afi][safi]; - peer->af_flags_invert[afi][safi] = conf->af_flags_invert[afi][safi]; + peer->af_flags[afi][safi] |= conf->af_flags[afi][safi] & ~pflags_ovrd; + peer->af_flags_invert[afi][safi] |= conf->af_flags_invert[afi][safi]; /* maximum-prefix */ - peer->pmax[afi][safi] = conf->pmax[afi][safi]; - peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi]; - peer->pmax_restart[afi][safi] = conf->pmax_restart[afi][safi]; + if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_MAX_PREFIX)) { + PEER_ATTR_INHERIT(peer, group, pmax[afi][safi]); + PEER_ATTR_INHERIT(peer, group, pmax_threshold[afi][safi]); + PEER_ATTR_INHERIT(peer, group, pmax_restart[afi][safi]); + } /* allowas-in */ - peer->allowas_in[afi][safi] = conf->allowas_in[afi][safi]; + if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_ALLOWAS_IN)) + PEER_ATTR_INHERIT(peer, group, allowas_in[afi][safi]); /* weight */ - peer->weight[afi][safi] = conf->weight[afi][safi]; + if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_WEIGHT)) + PEER_ATTR_INHERIT(peer, group, weight[afi][safi]); /* default-originate route-map */ - if (conf->default_rmap[afi][safi].name) { - if (peer->default_rmap[afi][safi].name) - XFREE(MTYPE_BGP_FILTER_NAME, - peer->default_rmap[afi][safi].name); - peer->default_rmap[afi][safi].name = - XSTRDUP(MTYPE_BGP_FILTER_NAME, - conf->default_rmap[afi][safi].name); - peer->default_rmap[afi][safi].map = - conf->default_rmap[afi][safi].map; + if (!CHECK_FLAG(pflags_ovrd, PEER_FLAG_DEFAULT_ORIGINATE)) { + PEER_STR_ATTR_INHERIT(peer, group, default_rmap[afi][safi].name, + MTYPE_ROUTE_MAP_NAME); + PEER_ATTR_INHERIT(peer, group, default_rmap[afi][safi].map); } /* inbound filter apply */ - if (gfilter->dlist[in].name && !pfilter->dlist[in].name) { - if (pfilter->dlist[in].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->dlist[in].name); - pfilter->dlist[in].name = - XSTRDUP(MTYPE_BGP_FILTER_NAME, gfilter->dlist[in].name); - pfilter->dlist[in].alist = gfilter->dlist[in].alist; + if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_DISTRIBUTE_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].dlist[in].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].dlist[in].alist); } - if (gfilter->plist[in].name && !pfilter->plist[in].name) { - if (pfilter->plist[in].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->plist[in].name); - pfilter->plist[in].name = - XSTRDUP(MTYPE_BGP_FILTER_NAME, gfilter->plist[in].name); - pfilter->plist[in].plist = gfilter->plist[in].plist; + if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_PREFIX_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].plist[in].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].plist[in].plist); } - if (gfilter->aslist[in].name && !pfilter->aslist[in].name) { - if (pfilter->aslist[in].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->aslist[in].name); - pfilter->aslist[in].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, - gfilter->aslist[in].name); - pfilter->aslist[in].aslist = gfilter->aslist[in].aslist; + if (!CHECK_FLAG(pfilter_ovrd[in], PEER_FT_FILTER_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].aslist[in].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].aslist[in].aslist); } - if (gfilter->map[RMAP_IN].name && !pfilter->map[RMAP_IN].name) { - if (pfilter->map[RMAP_IN].name) - XFREE(MTYPE_BGP_FILTER_NAME, - pfilter->map[RMAP_IN].name); - pfilter->map[RMAP_IN].name = XSTRDUP( - MTYPE_BGP_FILTER_NAME, gfilter->map[RMAP_IN].name); - pfilter->map[RMAP_IN].map = gfilter->map[RMAP_IN].map; + if (!CHECK_FLAG(pfilter_ovrd[RMAP_IN], PEER_FT_ROUTE_MAP)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].map[in].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].map[RMAP_IN].map); } /* outbound filter apply */ - if (gfilter->dlist[out].name) { - if (pfilter->dlist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->dlist[out].name); - pfilter->dlist[out].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, - gfilter->dlist[out].name); - pfilter->dlist[out].alist = gfilter->dlist[out].alist; - } else { - if (pfilter->dlist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->dlist[out].name); - pfilter->dlist[out].name = NULL; - pfilter->dlist[out].alist = NULL; - } - - if (gfilter->plist[out].name) { - if (pfilter->plist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->plist[out].name); - pfilter->plist[out].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, - gfilter->plist[out].name); - pfilter->plist[out].plist = gfilter->plist[out].plist; - } else { - if (pfilter->plist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->plist[out].name); - pfilter->plist[out].name = NULL; - pfilter->plist[out].plist = NULL; - } - - if (gfilter->aslist[out].name) { - if (pfilter->aslist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->aslist[out].name); - pfilter->aslist[out].name = XSTRDUP(MTYPE_BGP_FILTER_NAME, - gfilter->aslist[out].name); - pfilter->aslist[out].aslist = gfilter->aslist[out].aslist; - } else { - if (pfilter->aslist[out].name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->aslist[out].name); - pfilter->aslist[out].name = NULL; - pfilter->aslist[out].aslist = NULL; + if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_DISTRIBUTE_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].dlist[out].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].dlist[out].alist); } - if (gfilter->map[RMAP_OUT].name) { - if (pfilter->map[RMAP_OUT].name) - XFREE(MTYPE_BGP_FILTER_NAME, - pfilter->map[RMAP_OUT].name); - pfilter->map[RMAP_OUT].name = XSTRDUP( - MTYPE_BGP_FILTER_NAME, gfilter->map[RMAP_OUT].name); - pfilter->map[RMAP_OUT].map = gfilter->map[RMAP_OUT].map; - } else { - if (pfilter->map[RMAP_OUT].name) - XFREE(MTYPE_BGP_FILTER_NAME, - pfilter->map[RMAP_OUT].name); - pfilter->map[RMAP_OUT].name = NULL; - pfilter->map[RMAP_OUT].map = NULL; + if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_PREFIX_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].plist[out].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].plist[out].plist); } - if (gfilter->usmap.name) { - if (pfilter->usmap.name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->usmap.name); - pfilter->usmap.name = - XSTRDUP(MTYPE_BGP_FILTER_NAME, gfilter->usmap.name); - pfilter->usmap.map = gfilter->usmap.map; - } else { - if (pfilter->usmap.name) - XFREE(MTYPE_BGP_FILTER_NAME, pfilter->usmap.name); - pfilter->usmap.name = NULL; - pfilter->usmap.map = NULL; + if (!CHECK_FLAG(pfilter_ovrd[out], PEER_FT_FILTER_LIST)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].aslist[out].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].aslist[out].aslist); + } + + if (!CHECK_FLAG(pfilter_ovrd[RMAP_OUT], PEER_FT_ROUTE_MAP)) { + PEER_STR_ATTR_INHERIT(peer, group, + filter[afi][safi].map[RMAP_OUT].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, + filter[afi][safi].map[RMAP_OUT].map); + } + + /* nondirectional filter apply */ + if (!CHECK_FLAG(pfilter_ovrd[0], PEER_FT_UNSUPPRESS_MAP)) { + PEER_STR_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, group, filter[afi][safi].usmap.map); } } @@ -4766,9 +4736,11 @@ int peer_default_originate_unset(struct peer *peer, afi_t afi, safi_t safi) if (peer_group_active(peer)) { peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_DEFAULT_ORIGINATE); - PEER_STR_ATTR_INHERIT(MTYPE_ROUTE_MAP_NAME, peer, - default_rmap[afi][safi].name); - PEER_ATTR_INHERIT(peer, default_rmap[afi][safi].map); + PEER_STR_ATTR_INHERIT(peer, peer->group, + default_rmap[afi][safi].name, + MTYPE_ROUTE_MAP_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + default_rmap[afi][safi].map); } else { /* Otherwise remove flag and configuration from peer. */ peer_af_flag_unset(peer, afi, safi, @@ -4910,7 +4882,7 @@ int peer_weight_unset(struct peer *peer, afi_t afi, safi_t safi) /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_WEIGHT); - PEER_ATTR_INHERIT(peer, weight[afi][safi]); + PEER_ATTR_INHERIT(peer, peer->group, weight[afi][safi]); peer_on_policy_change(peer, afi, safi, 0); return 0; @@ -5256,7 +5228,7 @@ int peer_allowas_in_unset(struct peer *peer, afi_t afi, safi_t safi) peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN); peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_ALLOWAS_IN_ORIGIN); - PEER_ATTR_INHERIT(peer, allowas_in[afi][safi]); + PEER_ATTR_INHERIT(peer, peer->group, allowas_in[afi][safi]); peer_on_policy_change(peer, afi, safi, 0); return 0; @@ -5590,9 +5562,11 @@ int peer_distribute_unset(struct peer *peer, afi_t afi, safi_t safi, int direct) /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { - PEER_STR_ATTR_INHERIT(MTYPE_BGP_FILTER_NAME, peer, - filter[afi][safi].dlist[direct].name); - PEER_ATTR_INHERIT(peer, filter[afi][safi].dlist[direct].alist); + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].dlist[direct].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].dlist[direct].alist); } else { /* Otherwise remove configuration from peer. */ filter = &peer->filter[afi][safi]; @@ -5773,9 +5747,11 @@ int peer_prefix_list_unset(struct peer *peer, afi_t afi, safi_t safi, /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { - PEER_STR_ATTR_INHERIT(MTYPE_BGP_FILTER_NAME, peer, - filter[afi][safi].plist[direct].name); - PEER_ATTR_INHERIT(peer, filter[afi][safi].plist[direct].plist); + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].plist[direct].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].plist[direct].plist); } else { /* Otherwise remove configuration from peer. */ filter = &peer->filter[afi][safi]; @@ -5954,9 +5930,10 @@ int peer_aslist_unset(struct peer *peer, afi_t afi, safi_t safi, int direct) /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { - PEER_STR_ATTR_INHERIT(MTYPE_BGP_FILTER_NAME, peer, - filter[afi][safi].aslist[direct].name); - PEER_ATTR_INHERIT(peer, + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].aslist[direct].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, filter[afi][safi].aslist[direct].aslist); } else { /* Otherwise remove configuration from peer. */ @@ -6139,9 +6116,11 @@ int peer_route_map_unset(struct peer *peer, afi_t afi, safi_t safi, int direct) /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { - PEER_STR_ATTR_INHERIT(MTYPE_BGP_FILTER_NAME, peer, - filter[afi][safi].map[direct].name); - PEER_ATTR_INHERIT(peer, filter[afi][safi].map[direct].map); + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].map[direct].name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].map[direct].map); } else { /* Otherwise remove configuration from peer. */ filter = &peer->filter[afi][safi]; @@ -6248,9 +6227,11 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi) /* Inherit configuration from peer-group if peer is member. */ if (peer_group_active(peer)) { - PEER_STR_ATTR_INHERIT(MTYPE_BGP_FILTER_NAME, peer, - filter[afi][safi].usmap.name); - PEER_ATTR_INHERIT(peer, filter[afi][safi].usmap.map); + PEER_STR_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].usmap.name, + MTYPE_BGP_FILTER_NAME); + PEER_ATTR_INHERIT(peer, peer->group, + filter[afi][safi].usmap.map); } else { /* Otherwise remove configuration from peer. */ filter = &peer->filter[afi][safi]; @@ -6361,9 +6342,9 @@ int peer_maximum_prefix_unset(struct peer *peer, afi_t afi, safi_t safi) peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX); peer_af_flag_inherit(peer, afi, safi, PEER_FLAG_MAX_PREFIX_WARNING); - PEER_ATTR_INHERIT(peer, pmax[afi][safi]); - PEER_ATTR_INHERIT(peer, pmax_threshold[afi][safi]); - PEER_ATTR_INHERIT(peer, pmax_restart[afi][safi]); + PEER_ATTR_INHERIT(peer, peer->group, pmax[afi][safi]); + PEER_ATTR_INHERIT(peer, peer->group, pmax_threshold[afi][safi]); + PEER_ATTR_INHERIT(peer, peer->group, pmax_restart[afi][safi]); return 0; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 4048e8a8d9..fdc363d1f4 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1184,13 +1184,14 @@ struct peer { DECLARE_QOBJ_TYPE(peer) /* Inherit peer attribute from peer-group. */ -#define PEER_ATTR_INHERIT(peer, attr) ((peer)->attr = (peer)->group->conf->attr) -#define PEER_STR_ATTR_INHERIT(mt, peer, attr) \ +#define PEER_ATTR_INHERIT(peer, group, attr) \ + ((peer)->attr = (group)->conf->attr) +#define PEER_STR_ATTR_INHERIT(peer, group, attr, mt) \ do { \ if ((peer)->attr) \ XFREE(mt, (peer)->attr); \ - if ((peer)->group->conf->attr) \ - (peer)->attr = XSTRDUP(mt, (peer)->group->conf->attr); \ + if ((group)->conf->attr) \ + (peer)->attr = XSTRDUP(mt, (group)->conf->attr); \ else \ (peer)->attr = NULL; \ } while (0) diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index e4a3c6bb8a..3862028bb7 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -56,6 +56,11 @@ struct test { struct bgp *bgp; struct peer *peer; struct peer_group *group; + + struct { + bool use_ibgp; + bool use_iface_peer; + } o; }; struct test_config { @@ -256,6 +261,22 @@ static struct test_peer_attr test_peer_attrs[] = { .group_cmd = "default-originate route-map RM-GROUP", .u.flag = PEER_FLAG_DEFAULT_ORIGINATE, }, + { + .cmd = "distribute-list", + .peer_cmd = "distribute-list FL-PEER in", + .group_cmd = "distribute-list FL-GROUP in", + .type = PEER_AT_AF_FILTER, + .u.filter.flag = PEER_FT_DISTRIBUTE_LIST, + .u.filter.direct = FILTER_IN, + }, + { + .cmd = "distribute-list", + .peer_cmd = "distribute-list FL-PEER out", + .group_cmd = "distribute-list FL-GROUP out", + .type = PEER_AT_AF_FILTER, + .u.filter.flag = PEER_FT_DISTRIBUTE_LIST, + .u.filter.direct = FILTER_OUT, + }, { .cmd = "filter-list", .peer_cmd = "filter-list FL-PEER in", @@ -596,20 +617,13 @@ static void test_config_absent(struct test *test, const char *fmt, ...) va_end(ap); } -static struct test *test_new(const char *desc, bool use_ibgp, - bool use_iface_peer) +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(); - - 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"); @@ -619,18 +633,18 @@ static struct test *test_new(const char *desc, bool use_ibgp, 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); - if (use_iface_peer) { + 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, - use_ibgp ? cfg.local_asn : cfg.peer_asn); + test->o.use_ibgp ? cfg.local_asn : cfg.peer_asn); } else { test_execute(test, "neighbor %s remote-as %d", cfg.peer_address, - use_ibgp ? cfg.local_asn : cfg.peer_asn); + 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(); @@ -638,11 +652,11 @@ static struct test *test_new(const char *desc, bool use_ibgp, test->state = TEST_INTERNAL_ERROR; test->error = str_printf("could not retrieve default bgp instance"); - return test; + return; } /* Fetch peer instance. */ - if (use_iface_peer) { + if (test->o.use_iface_peer) { test->peer = peer_lookup_by_conf_if(test->bgp, cfg.peer_interface); } else { @@ -654,7 +668,7 @@ static struct test *test_new(const char *desc, bool use_ibgp, test->error = str_printf( "could not retrieve instance of bgp peer [%s]", cfg.peer_address); - return test; + return; } /* Fetch peer-group instance. */ @@ -664,8 +678,27 @@ static struct test *test_new(const char *desc, bool use_ibgp, test->error = str_printf( "could not retrieve instance of bgp peer-group [%s]", cfg.peer_group); - return test; + return; } +} + +static struct test *test_new(const char *desc, bool use_ibgp, + bool use_iface_peer) +{ + struct test *test; + + 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; + + test->vty = vty_new(); + test->vty->type = VTY_TERM; + test->vty->node = CONFIG_NODE; + + test_initialize(test); return test; }; @@ -822,12 +855,87 @@ static void test_peer_attr(struct test *test, struct test_peer_attr *pa) return; } - /* Test Preparation: Switch active address-family. */ + /* Test Preparation: Switch and activate address-family. */ + if (pa->type == PEER_AT_AF_FLAG || pa->type == PEER_AT_AF_FILTER) { + 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); + if (pa->type == PEER_AT_GLOBAL_FLAG || pa->type == PEER_AT_AF_FLAG) { + test_peer_flags(test, p, pa, true, true); + test_peer_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 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); + if (pa->type == PEER_AT_GLOBAL_FLAG || pa->type == PEER_AT_AF_FLAG) { + test_peer_flags(test, p, pa, true, true); + test_peer_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 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_present(test, "%sneighbor %s %s", ecg, g->name, group_cmd); + if (pa->type == PEER_AT_GLOBAL_FLAG || pa->type == PEER_AT_AF_FLAG) { + test_peer_flags(test, p, pa, true, true); + test_peer_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 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_GLOBAL_FLAG || pa->type == PEER_AT_AF_FLAG) { + test_peer_flags(test, p, pa, true, true); + test_peer_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 Preparation: Re-initialize test environment. */ + test_initialize(test); + p = test->peer; + g = test->group; + + /* Test Preparation: Switch and activate address-family. */ if (pa->type == PEER_AT_AF_FLAG || pa->type == PEER_AT_AF_FILTER) { 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. */ diff --git a/tests/bgpd/test_peer_attr.py b/tests/bgpd/test_peer_attr.py index 2c1623dea2..bd377ca3ad 100644 --- a/tests/bgpd/test_peer_attr.py +++ b/tests/bgpd/test_peer_attr.py @@ -80,6 +80,14 @@ TestFlag.okfail('peer\\ipv4-unicast\\default-originate route-map') TestFlag.okfail('peer\\ipv4-multicast\\default-originate route-map') TestFlag.okfail('peer\\ipv6-unicast\\default-originate route-map') TestFlag.okfail('peer\\ipv6-multicast\\default-originate route-map') +TestFlag.okfail('peer\\ipv4-unicast\\distribute-list') +TestFlag.okfail('peer\\ipv4-multicast\\distribute-list') +TestFlag.okfail('peer\\ipv6-unicast\\distribute-list') +TestFlag.okfail('peer\\ipv6-multicast\\distribute-list') +TestFlag.okfail('peer\\ipv4-unicast\\distribute-list') +TestFlag.okfail('peer\\ipv4-multicast\\distribute-list') +TestFlag.okfail('peer\\ipv6-unicast\\distribute-list') +TestFlag.okfail('peer\\ipv6-multicast\\distribute-list') TestFlag.okfail('peer\\ipv4-unicast\\filter-list') TestFlag.okfail('peer\\ipv4-multicast\\filter-list') TestFlag.okfail('peer\\ipv6-unicast\\filter-list') -- 2.39.5